#include "asterisk.h"
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <ldap.h>
#include "asterisk/channel.h"
#include "asterisk/logger.h"
#include "asterisk/config.h"
#include "asterisk/module.h"
#include "asterisk/lock.h"
#include "asterisk/options.h"
#include "asterisk/cli.h"
#include "asterisk/utils.h"
#include "asterisk/strings.h"
#include "asterisk/pbx.h"
#include "asterisk/linkedlists.h"
Go to the source code of this file.
Data Structures | |
struct | category_and_metric |
struct | ldap_table_config |
Table configuration. More... | |
struct | table_configs |
Should be locked before using it. More... | |
Defines | |
#define | MAXRESULT 2048 |
#define | RES_CONFIG_LDAP_CONF "res_ldap.conf" |
#define | RES_CONFIG_LDAP_DEFAULT_BASEDN "asterisk" |
Functions | |
static void | __reg_module (void) |
static void | __unreg_module (void) |
static void | append_var_and_value_to_filter (struct ast_str **filter, struct ldap_table_config *table_config, const char *name, const char *value) |
Append a name=value filter string. The filter string can grow. | |
static char * | cleaned_basedn (struct ast_channel *channel, const char *basedn) |
static int | compare_categories (const void *a, const void *b) |
Sorting alogrithm for qsort to find the order of the variables a and b. | |
static struct ast_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) |
See Asterisk doc. | |
static const char * | convert_attribute_name_from_ldap (struct ldap_table_config *table_config, const char *attribute_name) |
Convert ldap attribute name to variable name. | |
static const char * | convert_attribute_name_to_ldap (struct ldap_table_config *table_config, const char *attribute_name) |
Convert variable name to ldap attribute name - Should be locked before using it. | |
static int | is_ldap_connect_error (int err) |
Check if we have a connection error. | |
static struct ast_variable * | ldap_loadentry (struct ldap_table_config *table_config, const char *dn) |
Get LDAP entry by dn and return attributes as variables - Should be locked before using it This is used for setting the default values of an object(i.e., with accountBaseDN). | |
static int | ldap_reconnect (void) |
static void | ldap_table_config_add_attribute (struct ldap_table_config *table_config, const char *attribute_name, const char *attribute_value) |
add attribute to table config - Should be locked before using it | |
static int | load_module (void) |
static int | parse_config (void) |
parse the configuration file | |
static struct ast_variable * | realtime_ldap (const char *basedn, const char *table_name, va_list ap) |
See Asterisk doc. | |
static struct ast_variable ** | realtime_ldap_base (unsigned int *entries_count_ptr, const char *basedn, const char *table_name,...) |
same as realtime_ldap_base_ap but take variable arguments count list | |
static struct ast_variable ** | realtime_ldap_base_ap (unsigned int *entries_count_ptr, const char *basedn, const char *table_name, va_list ap) |
LDAP base function. | |
static struct ast_variable * | realtime_ldap_entry_to_var (struct ldap_table_config *table_config, LDAPMessage *ldap_entry) |
Get variables from ldap entry attributes. | |
static struct ast_variable ** | realtime_ldap_result_to_vars (struct ldap_table_config *table_config, LDAPMessage *ldap_result_msg, unsigned int *entries_count_ptr) |
Get variables from ldap entry attributes - Should be locked before using it. | |
static char * | realtime_ldap_status (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static struct ast_config * | realtime_multi_ldap (const char *basedn, const char *table_name, va_list ap) |
See Asterisk doc. | |
static int | reload (void) |
static int | replace_string_in_string (char *string, const char *search, const char *by) |
Replace <search> by <by> in string. | |
static int | semicolon_count_str (const char *somestr) |
for the semicolon delimiter | |
static int | semicolon_count_var (struct ast_variable *var) |
static char * | substituted (struct ast_channel *channel, const char *string) |
static struct ldap_table_config * | table_config_for_table_name (const char *table_name) |
Find a table_config - Should be locked before using it. | |
static struct ldap_table_config * | table_config_new (const char *table_name) |
Create a new table_config. | |
static void | table_configs_free (void) |
Free table_config. | |
static int | unload_module (void) |
static int | update2_ldap (const char *basedn, const char *table_name, va_list ap) |
static int | update_ldap (const char *basedn, const char *table_name, const char *attribute, const char *lookup, va_list ap) |
static struct ast_variable * | variable_named (struct ast_variable *var, const char *name) |
Find variable by name. | |
Variables | |
static struct ast_module_info | __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_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 = "8586c2a7d357cb591cc3a6607a8f62d1" , .load = load_module, .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_REALTIME_DRIVER, } |
static struct ast_module_info * | ast_module_info = &__mod_info |
static char | base_distinguished_name [512] |
static struct ldap_table_config * | base_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 = { { { NULL }, { 0 }, 0, { NULL }, { 0 }, {{{ 0 }}}, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP } , 1, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP } |
static LDAP * | ldapConn |
static char | pass [512] |
static struct ldap_table_config * | static_table_config |
static char | url [512] |
static char | user [512] |
static int | version |
Manuel Guesdon
Carl-Einar Thorner <cthorner@voicerd.com>
Russell Bryant <russell@digium.com>
Definition in file res_config_ldap.c.
#define MAXRESULT 2048 |
#define RES_CONFIG_LDAP_CONF "res_ldap.conf" |
#define RES_CONFIG_LDAP_DEFAULT_BASEDN "asterisk" |
static void __reg_module | ( | void | ) | [static] |
Definition at line 1807 of file res_config_ldap.c.
static void __unreg_module | ( | void | ) | [static] |
Definition at line 1807 of file res_config_ldap.c.
static void append_var_and_value_to_filter | ( | struct ast_str ** | filter, | |
struct ldap_table_config * | table_config, | |||
const char * | name, | |||
const char * | value | |||
) | [static] |
Append a name=value filter string. The filter string can grow.
Definition at line 691 of file res_config_ldap.c.
References ast_debug, ast_str_append(), ast_strdupa, convert_attribute_name_to_ldap(), filter(), len(), and replace_string_in_string().
Referenced by realtime_ldap_base_ap(), update2_ldap(), and update_ldap().
00694 { 00695 char *new_name = NULL; 00696 char *new_value = NULL; 00697 char *like_pos = strstr(name, " LIKE"); 00698 00699 ast_debug(2, "name='%s' value='%s'\n", name, value); 00700 00701 if (like_pos) { 00702 int len = like_pos - name; 00703 00704 name = new_name = ast_strdupa(name); 00705 new_name[len] = '\0'; 00706 value = new_value = ast_strdupa(value); 00707 replace_string_in_string(new_value, "\\_", "_"); 00708 replace_string_in_string(new_value, "%", "*"); 00709 } 00710 00711 name = convert_attribute_name_to_ldap(table_config, name); 00712 00713 ast_str_append(filter, 0, "(%s=%s)", name, value); 00714 }
static char* cleaned_basedn | ( | struct ast_channel * | channel, | |
const char * | basedn | |||
) | [static] |
Definition at line 640 of file res_config_ldap.c.
References ast_debug, ast_strlen_zero(), len(), and substituted().
Referenced by realtime_ldap_base_ap(), update2_ldap(), and update_ldap().
00641 { 00642 char *cbasedn = NULL; 00643 if (basedn) { 00644 char *p = NULL; 00645 cbasedn = substituted(channel, basedn); 00646 if (*cbasedn == '"') { 00647 cbasedn++; 00648 if (!ast_strlen_zero(cbasedn)) { 00649 int len = strlen(cbasedn); 00650 if (cbasedn[len - 1] == '"') 00651 cbasedn[len - 1] = '\0'; 00652 00653 } 00654 } 00655 p = cbasedn; 00656 while (*p) { 00657 if (*p == '|') 00658 *p = ','; 00659 p++; 00660 } 00661 } 00662 ast_debug(2, "basedn: '%s' => '%s' \n", basedn, cbasedn); 00663 return cbasedn; 00664 }
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.
a | pointer to category_and_metric struct | |
b | pointer to category_and_metric struct |
-1 | for if b is greater | |
0 | zero for equal | |
1 | if a is greater |
Definition at line 1016 of file res_config_ldap.c.
References category_and_metric::metric, category_and_metric::name, and category_and_metric::var_metric.
Referenced by config_ldap().
01017 { 01018 const struct category_and_metric *as = a; 01019 const struct category_and_metric *bs = b; 01020 01021 if (as->metric < bs->metric) { 01022 return -1; 01023 } else if (as->metric > bs->metric) { 01024 return 1; 01025 } else if (as->metric == bs->metric && strcmp(as->name, bs->name) != 0) { 01026 return strcmp(as->name, bs->name); 01027 } 01028 /* if the metric and the category name is the same, we check the variable metric */ 01029 if (as->var_metric < bs->var_metric) { 01030 return -1; 01031 } else if (as->var_metric > bs->var_metric) { 01032 return 1; 01033 } 01034 01035 return 0; 01036 }
static struct ast_config* config_ldap | ( | const char * | basedn, | |
const char * | table_name, | |||
const char * | file, | |||
struct ast_config * | cfg, | |||
struct ast_flags | config_flags, | |||
const char * | sugg_incl, | |||
const char * | who_asked | |||
) | [static] |
See Asterisk doc.
This is for Static Realtime (again: I think...)
load the configuration stuff for the .conf files called on a reload
Definition at line 1045 of file res_config_ldap.c.
References ast_calloc, ast_category_append(), ast_category_new(), ast_config_internal_load(), ast_debug, ast_free, ast_log(), ast_strlen_zero(), ast_variable_append(), ast_variable_new(), compare_categories(), LOG_ERROR, LOG_WARNING, ast_category::name, name, realtime_ldap_base(), RES_CONFIG_LDAP_CONF, ast_variable::value, and variable_named().
01047 { 01048 unsigned int vars_count = 0; 01049 struct ast_variable **vars; 01050 int i = 0; 01051 struct ast_variable *new_v = NULL; 01052 struct ast_category *cur_cat = NULL; 01053 const char *last_category = NULL; 01054 int last_category_metric = 0; 01055 struct category_and_metric *categories; 01056 struct ast_variable **p; 01057 01058 if (ast_strlen_zero(file) || !strcasecmp(file, RES_CONFIG_LDAP_CONF)) { 01059 ast_log(LOG_ERROR, "Missing configuration file: %s. Can't configure myself.\n", RES_CONFIG_LDAP_CONF); 01060 return NULL; 01061 } 01062 01063 vars = realtime_ldap_base(&vars_count, basedn, table_name, "filename", file, "commented", "FALSE", NULL); 01064 01065 if (!vars) { 01066 ast_log(LOG_WARNING, "Could not find config '%s' in directory.\n", file); 01067 return NULL; 01068 } 01069 01070 /*!\note Since the items come back in random order, they need to be sorted 01071 * first, and since the data could easily exceed stack size, this is 01072 * allocated from the heap. 01073 */ 01074 if (!(categories = ast_calloc(sizeof(*categories), vars_count))) { 01075 return NULL; 01076 } 01077 01078 for (vars_count = 0, p = vars; *p; p++) { 01079 struct ast_variable *category = variable_named(*p, "category"); 01080 struct ast_variable *cat_metric = variable_named(*p, "cat_metric"); 01081 struct ast_variable *var_name = variable_named(*p, "variable_name"); 01082 struct ast_variable *var_val = variable_named(*p, "variable_value"); 01083 struct ast_variable *var_metric = variable_named(*p, "var_metric"); 01084 struct ast_variable *dn = variable_named(*p, "dn"); 01085 01086 ast_debug(3, "category: %s\n", category->value); 01087 ast_debug(3, "var_name: %s\n", var_name->value); 01088 ast_debug(3, "var_val: %s\n", var_val->value); 01089 ast_debug(3, "cat_metric: %s\n", cat_metric->value); 01090 01091 if (!category) { 01092 ast_log(LOG_ERROR, "No category name in entry '%s' for file '%s'.\n", 01093 (dn ? dn->value : "?"), file); 01094 } else if (!cat_metric) { 01095 ast_log(LOG_ERROR, "No category metric in entry '%s'(category: %s) for file '%s'.\n", 01096 (dn ? dn->value : "?"), category->value, file); 01097 } else if (!var_metric) { 01098 ast_log(LOG_ERROR, "No variable metric in entry '%s'(category: %s) for file '%s'.\n", 01099 (dn ? dn->value : "?"), category->value, file); 01100 } else if (!var_name) { 01101 ast_log(LOG_ERROR, "No variable name in entry '%s' (category: %s metric: %s) for file '%s'.\n", 01102 (dn ? dn->value : "?"), category->value, 01103 cat_metric->value, file); 01104 } else if (!var_val) { 01105 ast_log(LOG_ERROR, "No variable value in entry '%s' (category: %s metric: %s variable: %s) for file '%s'.\n", 01106 (dn ? dn->value : "?"), category->value, 01107 cat_metric->value, var_name->value, file); 01108 } else { 01109 categories[vars_count].name = category->value; 01110 categories[vars_count].metric = atoi(cat_metric->value); 01111 categories[vars_count].variable_name = var_name->value; 01112 categories[vars_count].variable_value = var_val->value; 01113 categories[vars_count].var_metric = atoi(var_metric->value); 01114 vars_count++; 01115 } 01116 } 01117 01118 qsort(categories, vars_count, sizeof(*categories), compare_categories); 01119 01120 for (i = 0; i < vars_count; i++) { 01121 if (!strcmp(categories[i].variable_name, "#include")) { 01122 struct ast_flags flags = { 0 }; 01123 if (!ast_config_internal_load(categories[i].variable_value, cfg, flags, "", who_asked)) { 01124 break; 01125 } 01126 continue; 01127 } 01128 01129 if (!last_category || strcmp(last_category, categories[i].name) || 01130 last_category_metric != categories[i].metric) { 01131 01132 cur_cat = ast_category_new(categories[i].name, table_name, -1); 01133 if (!cur_cat) { 01134 break; 01135 } 01136 last_category = categories[i].name; 01137 last_category_metric = categories[i].metric; 01138 ast_category_append(cfg, cur_cat); 01139 } 01140 01141 if (!(new_v = ast_variable_new(categories[i].variable_name, categories[i].variable_value, table_name))) { 01142 break; 01143 } 01144 01145 ast_variable_append(cur_cat, new_v); 01146 } 01147 01148 ast_free(vars); 01149 ast_free(categories); 01150 01151 return cfg; 01152 }
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.
Definition at line 250 of file res_config_ldap.c.
References ARRAY_LEN, ldap_table_config::attributes, base_table_config, and ast_variable::name.
Referenced by realtime_ldap_entry_to_var(), and realtime_ldap_result_to_vars().
00252 { 00253 int i = 0; 00254 struct ldap_table_config *configs[] = { table_config, base_table_config }; 00255 00256 for (i = 0; i < ARRAY_LEN(configs); i++) { 00257 struct ast_variable *attribute; 00258 00259 if (!configs[i]) { 00260 continue; 00261 } 00262 00263 attribute = configs[i]->attributes; 00264 for (; attribute; attribute = attribute->next) { 00265 if (strcasecmp(attribute_name, attribute->value) == 0) { 00266 return attribute->name; 00267 } 00268 } 00269 } 00270 00271 return attribute_name; 00272 }
static const char* convert_attribute_name_to_ldap | ( | struct ldap_table_config * | table_config, | |
const char * | attribute_name | |||
) | [static] |
Convert variable name to ldap attribute name - Should be locked before using it.
Definition at line 224 of file res_config_ldap.c.
References ARRAY_LEN, ldap_table_config::attributes, base_table_config, and ast_variable::value.
Referenced by append_var_and_value_to_filter(), update2_ldap(), and update_ldap().
00226 { 00227 int i = 0; 00228 struct ldap_table_config *configs[] = { table_config, base_table_config }; 00229 00230 for (i = 0; i < ARRAY_LEN(configs); i++) { 00231 struct ast_variable *attribute; 00232 00233 if (!configs[i]) { 00234 continue; 00235 } 00236 00237 attribute = configs[i]->attributes; 00238 for (; attribute; attribute = attribute->next) { 00239 if (!strcasecmp(attribute_name, attribute->name)) { 00240 return attribute->value; 00241 } 00242 } 00243 } 00244 00245 return attribute_name; 00246 }
static int is_ldap_connect_error | ( | int | err | ) | [static] |
Check if we have a connection error.
Definition at line 543 of file res_config_ldap.c.
Referenced by ldap_loadentry(), realtime_ldap_base_ap(), update2_ldap(), and update_ldap().
00544 { 00545 return (err == LDAP_SERVER_DOWN || err == LDAP_TIMEOUT || err == LDAP_CONNECT_ERROR); 00546 }
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 551 of file res_config_ldap.c.
References ast_debug, ast_log(), ast_mutex_unlock, ast_realloc, ast_variables_destroy(), is_ldap_connect_error(), ldap_lock, ldap_reconnect(), ldapConn, LOG_ERROR, LOG_NOTICE, LOG_WARNING, realtime_ldap_result_to_vars(), and var.
Referenced by realtime_ldap_base_ap().
00553 { 00554 if (!table_config) { 00555 ast_log(LOG_ERROR, "No table config\n"); 00556 return NULL; 00557 } else { 00558 struct ast_variable **vars = NULL; 00559 struct ast_variable *var = NULL; 00560 int result = -1; 00561 LDAPMessage *ldap_result_msg = NULL; 00562 int tries = 0; 00563 00564 ast_debug(2, "ldap_loadentry dn=%s\n", dn); 00565 00566 do { 00567 result = ldap_search_ext_s(ldapConn, dn, LDAP_SCOPE_BASE, 00568 "(objectclass=*)", NULL, 0, NULL, NULL, NULL, LDAP_NO_LIMIT, &ldap_result_msg); 00569 if (result != LDAP_SUCCESS && is_ldap_connect_error(result)) { 00570 ast_log(LOG_WARNING, "Failed to query directory. Try %d/3\n", tries + 1); 00571 tries++; 00572 if (tries < 3) { 00573 usleep(500000L * tries); 00574 if (ldapConn) { 00575 ldap_unbind_ext_s(ldapConn, NULL, NULL); 00576 ldapConn = NULL; 00577 } 00578 if (!ldap_reconnect()) { 00579 break; 00580 } 00581 } 00582 } 00583 } while (result != LDAP_SUCCESS && tries < 3 && is_ldap_connect_error(result)); 00584 00585 if (result != LDAP_SUCCESS) { 00586 ast_log(LOG_WARNING, "Failed to query directory. Error: %s.\n", ldap_err2string(result)); 00587 ast_debug(2, "dn=%s\n", dn); 00588 ast_mutex_unlock(&ldap_lock); 00589 return NULL; 00590 } else { 00591 int num_entry = 0; 00592 unsigned int *entries_count_ptr = NULL; /*!< not using this */ 00593 00594 if ((num_entry = ldap_count_entries(ldapConn, ldap_result_msg)) > 0) { 00595 ast_debug(3, "num_entry: %d\n", num_entry); 00596 00597 vars = realtime_ldap_result_to_vars(table_config, ldap_result_msg, entries_count_ptr); 00598 if (num_entry > 1) { 00599 ast_log(LOG_NOTICE, "More than one entry for dn=%s. Take only 1st one\n", dn); 00600 } 00601 } else { 00602 ast_debug(2, "Could not find any entry dn=%s.\n", dn); 00603 } 00604 } 00605 ldap_msgfree(ldap_result_msg); 00606 00607 /* Chopping \a vars down to one variable */ 00608 if (vars != NULL) { 00609 struct ast_variable **p = vars; 00610 p++; 00611 var = *p; 00612 while (var) { 00613 ast_variables_destroy(var); 00614 p++; 00615 } 00616 vars = ast_realloc(vars, sizeof(struct ast_variable *)); 00617 } 00618 00619 var = *vars; 00620 00621 return var; 00622 } 00623 }
static int ldap_reconnect | ( | void | ) | [static] |
Definition at line 1707 of file res_config_ldap.c.
References ast_debug, ast_log(), ast_strlen_zero(), connect_time, ldapConn, LOG_ERROR, LOG_WARNING, pass, url, and version.
Referenced by ldap_loadentry(), load_module(), realtime_ldap_base_ap(), reload(), update2_ldap(), and update_ldap().
01708 { 01709 int bind_result = 0; 01710 struct berval cred; 01711 01712 if (ldapConn) { 01713 ast_debug(2, "Everything seems fine.\n"); 01714 return 1; 01715 } 01716 01717 if (ast_strlen_zero(url)) { 01718 ast_log(LOG_ERROR, "Not enough parameters to connect to ldap directory\n"); 01719 return 0; 01720 } 01721 01722 if (LDAP_SUCCESS != ldap_initialize(&ldapConn, url)) { 01723 ast_log(LOG_ERROR, "Failed to init ldap connection to '%s'. Check debug for more info.\n", url); 01724 return 0; 01725 } 01726 01727 if (LDAP_OPT_SUCCESS != ldap_set_option(ldapConn, LDAP_OPT_PROTOCOL_VERSION, &version)) { 01728 ast_log(LOG_WARNING, "Unable to set LDAP protocol version to %d, falling back to default.\n", version); 01729 } 01730 01731 if (!ast_strlen_zero(user)) { 01732 ast_debug(2, "bind to '%s' as user '%s'\n", url, user); 01733 cred.bv_val = (char *) pass; 01734 cred.bv_len = strlen(pass); 01735 bind_result = ldap_sasl_bind_s(ldapConn, user, LDAP_SASL_SIMPLE, &cred, NULL, NULL, NULL); 01736 } else { 01737 ast_debug(2, "bind %s anonymously\n", url); 01738 cred.bv_val = NULL; 01739 cred.bv_len = 0; 01740 bind_result = ldap_sasl_bind_s(ldapConn, NULL, LDAP_SASL_SIMPLE, &cred, NULL, NULL, NULL); 01741 } 01742 if (bind_result == LDAP_SUCCESS) { 01743 ast_debug(2, "Successfully connected to directory.\n"); 01744 connect_time = time(NULL); 01745 return 1; 01746 } else { 01747 ast_log(LOG_WARNING, "bind failed: %s\n", ldap_err2string(bind_result)); 01748 ldap_unbind_ext_s(ldapConn, NULL, NULL); 01749 ldapConn = NULL; 01750 return 0; 01751 } 01752 }
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 181 of file res_config_ldap.c.
References ast_strlen_zero(), ast_variable_new(), ldap_table_config::attributes, ldap_table_config::table_name, and var.
Referenced by parse_config().
00183 { 00184 struct ast_variable *var; 00185 00186 if (ast_strlen_zero(attribute_name) || ast_strlen_zero(attribute_value)) { 00187 return; 00188 } 00189 00190 if (!(var = ast_variable_new(attribute_name, attribute_value, table_config->table_name))) { 00191 return; 00192 } 00193 00194 if (table_config->attributes) { 00195 var->next = table_config->attributes; 00196 } 00197 table_config->attributes = var; 00198 }
static int load_module | ( | void | ) | [static] |
Definition at line 1535 of file res_config_ldap.c.
References ARRAY_LEN, ast_cli_register_multiple(), ast_config_engine_register(), ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_verb, ldap_cli, ldap_engine, ldap_lock, ldap_reconnect(), LOG_ERROR, LOG_WARNING, and parse_config().
01536 { 01537 if (parse_config() < 0) { 01538 ast_log(LOG_ERROR, "Cannot load LDAP RealTime driver.\n"); 01539 return 0; 01540 } 01541 01542 ast_mutex_lock(&ldap_lock); 01543 01544 if (!ldap_reconnect()) { 01545 ast_log(LOG_WARNING, "Couldn't establish connection to LDAP directory. Check debug.\n"); 01546 } 01547 01548 ast_config_engine_register(&ldap_engine); 01549 ast_verb(1, "LDAP RealTime driver loaded.\n"); 01550 ast_cli_register_multiple(ldap_cli, ARRAY_LEN(ldap_cli)); 01551 01552 ast_mutex_unlock(&ldap_lock); 01553 01554 return 0; 01555 }
static int parse_config | ( | void | ) | [static] |
parse the configuration file
< using the [config] context for Static RealTime
Definition at line 1607 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, base_table_config, config, config_flags, CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEMISSING, ldap_table_config::entry, ldap_table_config_add_attribute(), LOG_ERROR, LOG_NOTICE, LOG_WARNING, pass, RES_CONFIG_LDAP_CONF, RES_CONFIG_LDAP_DEFAULT_BASEDN, static_table_config, table_config_for_table_name(), table_config_new(), table_configs_free(), url, var, and version.
01608 { 01609 struct ast_config *config; 01610 struct ast_flags config_flags = {0}; 01611 const char *s, *host; 01612 int port; 01613 char *category_name = NULL; 01614 01615 /* Make sure that global variables are reset */ 01616 url[0] = '\0'; 01617 user[0] = '\0'; 01618 pass[0] = '\0'; 01619 base_distinguished_name[0] = '\0'; 01620 version = 3; 01621 01622 config = ast_config_load(RES_CONFIG_LDAP_CONF, config_flags); 01623 if (config == CONFIG_STATUS_FILEMISSING || config == CONFIG_STATUS_FILEINVALID) { 01624 ast_log(LOG_ERROR, "Cannot load configuration file: %s\n", RES_CONFIG_LDAP_CONF); 01625 return -1; 01626 } 01627 01628 if (!(s = ast_variable_retrieve(config, "_general", "user"))) { 01629 ast_log(LOG_NOTICE, "No directory user found, anonymous binding as default.\n"); 01630 user[0] = '\0'; 01631 } else { 01632 ast_copy_string(user, s, sizeof(user)); 01633 } 01634 01635 if (!ast_strlen_zero(user)) { 01636 if (!(s = ast_variable_retrieve(config, "_general", "pass"))) { 01637 ast_log(LOG_WARNING, "No directory password found, using 'asterisk' as default.\n"); 01638 ast_copy_string(pass, "asterisk", sizeof(pass)); 01639 } else { 01640 ast_copy_string(pass, s, sizeof(pass)); 01641 } 01642 } 01643 01644 /* URL is preferred, use host and port if not found */ 01645 if ((s = ast_variable_retrieve(config, "_general", "url"))) { 01646 ast_copy_string(url, s, sizeof(url)); 01647 } else if ((host = ast_variable_retrieve(config, "_general", "host"))) { 01648 if (!(s = ast_variable_retrieve(config, "_general", "port")) || sscanf(s, "%5d", &port) != 1 || port > 65535) { 01649 ast_log(LOG_NOTICE, "No directory port found, using 389 as default.\n"); 01650 port = 389; 01651 } 01652 01653 snprintf(url, sizeof(url), "ldap://%s:%d", host, port); 01654 } else { 01655 ast_log(LOG_ERROR, "No directory URL or host found.\n"); 01656 ast_config_destroy(config); 01657 return -1; 01658 } 01659 01660 if (!(s = ast_variable_retrieve(config, "_general", "basedn"))) { 01661 ast_log(LOG_ERROR, "No LDAP base dn found, using '%s' as default.\n", RES_CONFIG_LDAP_DEFAULT_BASEDN); 01662 ast_copy_string(base_distinguished_name, RES_CONFIG_LDAP_DEFAULT_BASEDN, sizeof(base_distinguished_name)); 01663 } else 01664 ast_copy_string(base_distinguished_name, s, sizeof(base_distinguished_name)); 01665 01666 if (!(s = ast_variable_retrieve(config, "_general", "version")) && !(s = ast_variable_retrieve(config, "_general", "protocol"))) { 01667 ast_log(LOG_NOTICE, "No explicit LDAP version found, using 3 as default.\n"); 01668 } else if (sscanf(s, "%30d", &version) != 1 || version < 1 || version > 6) { 01669 ast_log(LOG_WARNING, "Invalid LDAP version '%s', using 3 as default.\n", s); 01670 version = 3; 01671 } 01672 01673 table_configs_free(); 01674 01675 while ((category_name = ast_category_browse(config, category_name))) { 01676 int is_general = (strcasecmp(category_name, "_general") == 0); 01677 int is_config = (strcasecmp(category_name, "config") == 0); /*!< using the [config] context for Static RealTime */ 01678 struct ast_variable *var = ast_variable_browse(config, category_name); 01679 01680 if (var) { 01681 struct ldap_table_config *table_config = 01682 table_config_for_table_name(category_name); 01683 if (!table_config) { 01684 table_config = table_config_new(category_name); 01685 AST_LIST_INSERT_HEAD(&table_configs, table_config, entry); 01686 if (is_general) 01687 base_table_config = table_config; 01688 if (is_config) 01689 static_table_config = table_config; 01690 } 01691 for (; var; var = var->next) { 01692 if (!strcasecmp(var->name, "additionalFilter")) { 01693 table_config->additional_filter = ast_strdup(var->value); 01694 } else { 01695 ldap_table_config_add_attribute(table_config, var->name, var->value); 01696 } 01697 } 01698 } 01699 } 01700 01701 ast_config_destroy(config); 01702 01703 return 1; 01704 }
static struct ast_variable* realtime_ldap | ( | const char * | basedn, | |
const char * | table_name, | |||
va_list | ap | |||
) | [static] |
See Asterisk doc.
For Realtime Dynamic(i.e., switch, queues, and directory) -- I think
Definition at line 918 of file res_config_ldap.c.
References free, ast_variable::next, realtime_ldap_base_ap(), and var.
00920 { 00921 struct ast_variable **vars = realtime_ldap_base_ap(NULL, basedn, table_name, ap); 00922 struct ast_variable *var = NULL; 00923 00924 if (vars) { 00925 struct ast_variable *last_var = NULL; 00926 struct ast_variable **p = vars; 00927 while (*p) { 00928 if (last_var) { 00929 while (last_var->next) { 00930 last_var = last_var->next; 00931 } 00932 last_var->next = *p; 00933 } else { 00934 var = *p; 00935 last_var = var; 00936 } 00937 p++; 00938 } 00939 free(vars); 00940 } 00941 return var; 00942 }
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 901 of file res_config_ldap.c.
References realtime_ldap_base_ap().
Referenced by config_ldap().
00903 { 00904 struct ast_variable **vars = NULL; 00905 va_list ap; 00906 00907 va_start(ap, table_name); 00908 vars = realtime_ldap_base_ap(entries_count_ptr, basedn, table_name, ap); 00909 va_end(ap); 00910 00911 return vars; 00912 }
static struct ast_variable** realtime_ldap_base_ap | ( | unsigned int * | entries_count_ptr, | |
const char * | basedn, | |||
const char * | table_name, | |||
va_list | ap | |||
) | [static] |
LDAP base function.
entries_count_ptr | is a pointer to found entries count (can be NULL) | |
basedn | is the base DN | |
table_name | is the table_name (used dor attribute convertion and additional filter) | |
ap | contains null terminated list of pairs name/value |
Definition at line 724 of file res_config_ldap.c.
References ldap_table_config::additional_filter, append_var_and_value_to_filter(), ast_debug, ast_free, ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_str_append(), ast_str_buffer(), ast_str_create(), ast_variables_destroy(), base_table_config, cleaned_basedn(), filter(), is_ldap_connect_error(), ldap_loadentry(), ldap_lock, ldap_reconnect(), ldapConn, LOG_DEBUG, LOG_ERROR, LOG_WARNING, ast_variable::name, ast_variable::next, realtime_ldap_result_to_vars(), table_config_for_table_name(), and ast_variable::value.
Referenced by realtime_ldap(), realtime_ldap_base(), and realtime_multi_ldap().
00726 { 00727 struct ast_variable **vars = NULL; 00728 const char *newparam = NULL; 00729 const char *newval = NULL; 00730 struct ldap_table_config *table_config = NULL; 00731 char *clean_basedn = cleaned_basedn(NULL, basedn); 00732 struct ast_str *filter = NULL; 00733 int tries = 0; 00734 int result = 0; 00735 LDAPMessage *ldap_result_msg = NULL; 00736 00737 if (!table_name) { 00738 ast_log(LOG_ERROR, "No table_name specified.\n"); 00739 ast_free(clean_basedn); 00740 return NULL; 00741 } 00742 00743 if (!(filter = ast_str_create(80))) { 00744 ast_log(LOG_ERROR, "Can't initialize data structures.n"); 00745 ast_free(clean_basedn); 00746 return NULL; 00747 } 00748 00749 /* Get the first parameter and first value in our list of passed paramater/value pairs */ 00750 newparam = va_arg(ap, const char *); 00751 newval = va_arg(ap, const char *); 00752 00753 if (!newparam || !newval) { 00754 ast_log(LOG_ERROR, "Realtime retrieval requires at least 1 parameter" 00755 " and 1 value to search on.\n"); 00756 ast_free(filter); 00757 ast_free(clean_basedn); 00758 return NULL; 00759 } 00760 00761 ast_mutex_lock(&ldap_lock); 00762 00763 /* We now have our complete statement; Lets connect to the server and execute it. */ 00764 if (!ldap_reconnect()) { 00765 ast_mutex_unlock(&ldap_lock); 00766 ast_free(filter); 00767 ast_free(clean_basedn); 00768 return NULL; 00769 } 00770 00771 table_config = table_config_for_table_name(table_name); 00772 if (!table_config) { 00773 ast_log(LOG_WARNING, "No table named '%s'.\n", table_name); 00774 ast_mutex_unlock(&ldap_lock); 00775 ast_free(filter); 00776 ast_free(clean_basedn); 00777 return NULL; 00778 } 00779 00780 ast_str_append(&filter, 0, "(&"); 00781 00782 if (table_config && table_config->additional_filter) { 00783 ast_str_append(&filter, 0, "%s", table_config->additional_filter); 00784 } 00785 if (table_config != base_table_config && base_table_config && 00786 base_table_config->additional_filter) { 00787 ast_str_append(&filter, 0, "%s", base_table_config->additional_filter); 00788 } 00789 00790 /* Create the first part of the query using the first parameter/value pairs we just extracted */ 00791 /* If there is only 1 set, then we have our query. Otherwise, loop thru the list and concat */ 00792 00793 append_var_and_value_to_filter(&filter, table_config, newparam, newval); 00794 while ((newparam = va_arg(ap, const char *))) { 00795 newval = va_arg(ap, const char *); 00796 append_var_and_value_to_filter(&filter, table_config, newparam, newval); 00797 } 00798 ast_str_append(&filter, 0, ")"); 00799 00800 do { 00801 /* freeing ldap_result further down */ 00802 result = ldap_search_ext_s(ldapConn, clean_basedn, 00803 LDAP_SCOPE_SUBTREE, ast_str_buffer(filter), NULL, 0, NULL, NULL, NULL, LDAP_NO_LIMIT, 00804 &ldap_result_msg); 00805 if (result != LDAP_SUCCESS && is_ldap_connect_error(result)) { 00806 ast_log(LOG_DEBUG, "Failed to query directory. Try %d/10\n", tries + 1); 00807 if (++tries < 10) { 00808 usleep(1); 00809 if (ldapConn) { 00810 ldap_unbind_ext_s(ldapConn, NULL, NULL); 00811 ldapConn = NULL; 00812 } 00813 if (!ldap_reconnect()) { 00814 break; 00815 } 00816 } 00817 } 00818 } while (result != LDAP_SUCCESS && tries < 10 && is_ldap_connect_error(result)); 00819 00820 if (result != LDAP_SUCCESS) { 00821 ast_log(LOG_WARNING, "Failed to query directory. Error: %s.\n", ldap_err2string(result)); 00822 ast_log(LOG_WARNING, "Query: %s\n", ast_str_buffer(filter)); 00823 } else { 00824 /* this is where we create the variables from the search result 00825 * freeing this \a vars outside this function */ 00826 if (ldap_count_entries(ldapConn, ldap_result_msg) > 0) { 00827 /* is this a static var or some other? they are handled different for delimited values */ 00828 vars = realtime_ldap_result_to_vars(table_config, ldap_result_msg, entries_count_ptr); 00829 } else { 00830 ast_debug(1, "Could not find any entry matching %s in base dn %s.\n", ast_str_buffer(filter), clean_basedn); 00831 } 00832 00833 ldap_msgfree(ldap_result_msg); 00834 00835 /* TODO: get the default variables from the accountBaseDN, not implemented with delimited values */ 00836 if (vars) { 00837 struct ast_variable **p = vars; 00838 while (*p) { 00839 struct ast_variable *append_var = NULL; 00840 struct ast_variable *tmp = *p; 00841 while (tmp) { 00842 if (strcasecmp(tmp->name, "accountBaseDN") == 0) { 00843 /* Get the variable to compare with for the defaults */ 00844 struct ast_variable *base_var = ldap_loadentry(table_config, tmp->value); 00845 00846 while (base_var) { 00847 struct ast_variable *next = base_var->next; 00848 struct ast_variable *test_var = *p; 00849 int base_var_found = 0; 00850 00851 /* run throught the default values and fill it inn if it is missing */ 00852 while (test_var) { 00853 if (strcasecmp(test_var->name, base_var->name) == 0) { 00854 base_var_found = 1; 00855 break; 00856 } else { 00857 test_var = test_var->next; 00858 } 00859 } 00860 if (base_var_found) { 00861 base_var->next = NULL; 00862 ast_variables_destroy(base_var); 00863 base_var = next; 00864 } else { 00865 if (append_var) { 00866 base_var->next = append_var; 00867 } else { 00868 base_var->next = NULL; 00869 } 00870 append_var = base_var; 00871 base_var = next; 00872 } 00873 } 00874 } 00875 if (!tmp->next && append_var) { 00876 tmp->next = append_var; 00877 tmp = NULL; 00878 } else { 00879 tmp = tmp->next; 00880 } 00881 } 00882 p++; 00883 } 00884 } 00885 } 00886 00887 if (filter) { 00888 ast_free(filter); 00889 } 00890 00891 if (clean_basedn) { 00892 ast_free(clean_basedn); 00893 } 00894 00895 ast_mutex_unlock(&ldap_lock); 00896 00897 return vars; 00898 }
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.
Definition at line 278 of file res_config_ldap.c.
References ast_debug, ast_strlen_zero(), ast_variable_new(), convert_attribute_name_from_ldap(), ldapConn, ast_variable::next, ldap_table_config::table_name, value, and var.
Referenced by realtime_ldap_result_to_vars().
00280 { 00281 BerElement *ber = NULL; 00282 struct ast_variable *var = NULL; 00283 struct ast_variable *prev = NULL; 00284 int is_delimited = 0; 00285 int i = 0; 00286 char *ldap_attribute_name; 00287 struct berval *value; 00288 int pos = 0; 00289 00290 ldap_attribute_name = ldap_first_attribute(ldapConn, ldap_entry, &ber); 00291 00292 while (ldap_attribute_name) { 00293 struct berval **values = NULL; 00294 const char *attribute_name = convert_attribute_name_from_ldap(table_config, ldap_attribute_name); 00295 int is_realmed_password_attribute = strcasecmp(attribute_name, "md5secret") == 0; 00296 00297 values = ldap_get_values_len(ldapConn, ldap_entry, ldap_attribute_name); /* these are freed at the end */ 00298 if (values) { 00299 struct berval **v; 00300 char *valptr; 00301 00302 for (v = values; *v; v++) { 00303 value = *v; 00304 valptr = value->bv_val; 00305 ast_debug(2, "LINE(%d) attribute_name: %s LDAP value: %s\n", __LINE__, attribute_name, valptr); 00306 if (is_realmed_password_attribute) { 00307 if (!strncasecmp(valptr, "{md5}", 5)) { 00308 valptr += 5; 00309 } 00310 ast_debug(2, "md5: %s\n", valptr); 00311 } 00312 if (valptr) { 00313 /* ok, so looping through all delimited values except the last one (not, last character is not delimited...) */ 00314 if (is_delimited) { 00315 i = 0; 00316 pos = 0; 00317 while (!ast_strlen_zero(valptr + i)) { 00318 if (valptr[i] == ';') { 00319 valptr[i] = '\0'; 00320 if (prev) { 00321 prev->next = ast_variable_new(attribute_name, &valptr[pos], table_config->table_name); 00322 if (prev->next) { 00323 prev = prev->next; 00324 } 00325 } else { 00326 prev = var = ast_variable_new(attribute_name, &valptr[pos], table_config->table_name); 00327 } 00328 pos = i + 1; 00329 } 00330 i++; 00331 } 00332 } 00333 /* for the last delimited value or if the value is not delimited: */ 00334 if (prev) { 00335 prev->next = ast_variable_new(attribute_name, &valptr[pos], table_config->table_name); 00336 if (prev->next) { 00337 prev = prev->next; 00338 } 00339 } else { 00340 prev = var = ast_variable_new(attribute_name, &valptr[pos], table_config->table_name); 00341 } 00342 } 00343 } 00344 ldap_value_free_len(values); 00345 } 00346 ldap_attribute_name = ldap_next_attribute(ldapConn, ldap_entry, ber); 00347 } 00348 ber_free(ber, 0); 00349 00350 return var; 00351 }
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.
Definition at line 359 of file res_config_ldap.c.
References ast_calloc, ast_debug, ast_strdup, ast_strlen_zero(), ast_variable_new(), ast_variables_destroy(), convert_attribute_name_from_ldap(), free, ldapConn, ast_variable::next, option_debug, realtime_ldap_entry_to_var(), semicolon_count_str(), semicolon_count_var(), static_table_config, ldap_table_config::table_name, ast_variable::value, value, var, and variable_named().
Referenced by ldap_loadentry(), and realtime_ldap_base_ap().
00361 { 00362 struct ast_variable **vars; 00363 int i = 0; 00364 int tot_count = 0; 00365 int entry_index = 0; 00366 LDAPMessage *ldap_entry = NULL; 00367 BerElement *ber = NULL; 00368 struct ast_variable *var = NULL; 00369 struct ast_variable *prev = NULL; 00370 int is_delimited = 0; 00371 char *delim_value = NULL; 00372 int delim_tot_count = 0; 00373 int delim_count = 0; 00374 00375 /* First find the total count */ 00376 ldap_entry = ldap_first_entry(ldapConn, ldap_result_msg); 00377 00378 for (tot_count = 0; ldap_entry; tot_count++) { 00379 struct ast_variable *tmp = realtime_ldap_entry_to_var(table_config, ldap_entry); 00380 tot_count += semicolon_count_var(tmp); 00381 ldap_entry = ldap_next_entry(ldapConn, ldap_entry); 00382 ast_variables_destroy(tmp); 00383 } 00384 00385 if (entries_count_ptr) { 00386 *entries_count_ptr = tot_count; 00387 } 00388 00389 /* Now that we have the total count we allocate space and create the variables 00390 * Remember that each element in vars is a linked list that points to realtime variable. 00391 * If the we are dealing with a static realtime variable we create a new element in the \a vars array for each delimited 00392 * 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. 00393 * This memory must be freed outside of this function. */ 00394 vars = ast_calloc(sizeof(struct ast_variable *), tot_count + 1); 00395 00396 ldap_entry = ldap_first_entry(ldapConn, ldap_result_msg); 00397 00398 i = 0; 00399 00400 /* For each static realtime variable we may create several entries in the \a vars array if it's delimited */ 00401 for (entry_index = 0; ldap_entry; ) { 00402 int pos = 0; 00403 delim_value = NULL; 00404 delim_tot_count = 0; 00405 delim_count = 0; 00406 00407 do { /* while delim_count */ 00408 00409 /* Starting new static var */ 00410 char *ldap_attribute_name = ldap_first_attribute(ldapConn, ldap_entry, &ber); 00411 struct berval *value; 00412 while (ldap_attribute_name) { 00413 00414 const char *attribute_name = convert_attribute_name_from_ldap(table_config, ldap_attribute_name); 00415 int is_realmed_password_attribute = strcasecmp(attribute_name, "md5secret") == 0; 00416 struct berval **values = NULL; 00417 00418 values = ldap_get_values_len(ldapConn, ldap_entry, ldap_attribute_name); 00419 if (values) { 00420 struct berval **v; 00421 char *valptr; 00422 00423 for (v = values; *v; v++) { 00424 value = *v; 00425 valptr = value->bv_val; 00426 if (is_realmed_password_attribute) { 00427 if (strncasecmp(valptr, "{md5}", 5) == 0) { 00428 valptr += 5; 00429 } 00430 ast_debug(2, "md5: %s\n", valptr); 00431 } 00432 if (valptr) { 00433 if (delim_value == NULL && !is_realmed_password_attribute 00434 && (static_table_config != table_config || strcmp(attribute_name, "variable_value") == 0)) { 00435 00436 delim_value = ast_strdup(valptr); 00437 00438 if ((delim_tot_count = semicolon_count_str(delim_value)) > 0) { 00439 ast_debug(4, "LINE(%d) is delimited %d times: %s\n", __LINE__, delim_tot_count, delim_value); 00440 is_delimited = 1; 00441 } 00442 } 00443 00444 if (is_delimited != 0 && !is_realmed_password_attribute 00445 && (static_table_config != table_config || strcmp(attribute_name, "variable_value") == 0) ) { 00446 /* for non-Static RealTime, first */ 00447 00448 for (i = pos; !ast_strlen_zero(valptr + i); i++) { 00449 ast_debug(4, "LINE(%d) DELIM pos: %d i: %d\n", __LINE__, pos, i); 00450 if (delim_value[i] == ';') { 00451 delim_value[i] = '\0'; 00452 00453 ast_debug(2, "LINE(%d) DELIM - attribute_name: %s value: %s pos: %d\n", __LINE__, attribute_name, &delim_value[pos], pos); 00454 00455 if (prev) { 00456 prev->next = ast_variable_new(attribute_name, &delim_value[pos], table_config->table_name); 00457 if (prev->next) { 00458 prev = prev->next; 00459 } 00460 } else { 00461 prev = var = ast_variable_new(attribute_name, &delim_value[pos], table_config->table_name); 00462 } 00463 pos = i + 1; 00464 00465 if (static_table_config == table_config) { 00466 break; 00467 } 00468 } 00469 } 00470 if (ast_strlen_zero(valptr + i)) { 00471 ast_debug(4, "LINE(%d) DELIM pos: %d i: %d delim_count: %d\n", __LINE__, pos, i, delim_count); 00472 /* Last delimited value */ 00473 ast_debug(4, "LINE(%d) DELIM - attribute_name: %s value: %s pos: %d\n", __LINE__, attribute_name, &delim_value[pos], pos); 00474 if (prev) { 00475 prev->next = ast_variable_new(attribute_name, &delim_value[pos], table_config->table_name); 00476 if (prev->next) { 00477 prev = prev->next; 00478 } 00479 } else { 00480 prev = var = ast_variable_new(attribute_name, &delim_value[pos], table_config->table_name); 00481 } 00482 /* Remembering to free memory */ 00483 is_delimited = 0; 00484 pos = 0; 00485 } 00486 free(delim_value); 00487 delim_value = NULL; 00488 00489 ast_debug(4, "LINE(%d) DELIM pos: %d i: %d\n", __LINE__, pos, i); 00490 } else { 00491 /* not delimited */ 00492 if (delim_value) { 00493 free(delim_value); 00494 delim_value = NULL; 00495 } 00496 ast_debug(2, "LINE(%d) attribute_name: %s value: %s\n", __LINE__, attribute_name, valptr); 00497 00498 if (prev) { 00499 prev->next = ast_variable_new(attribute_name, valptr, table_config->table_name); 00500 if (prev->next) { 00501 prev = prev->next; 00502 } 00503 } else { 00504 prev = var = ast_variable_new(attribute_name, valptr, table_config->table_name); 00505 } 00506 } 00507 } 00508 } /*!< for (v = values; *v; v++) */ 00509 ldap_value_free_len(values); 00510 }/*!< if (values) */ 00511 ldap_attribute_name = ldap_next_attribute(ldapConn, ldap_entry, ber); 00512 } /*!< while (ldap_attribute_name) */ 00513 ber_free(ber, 0); 00514 if (static_table_config == table_config) { 00515 if (option_debug > 2) { 00516 const struct ast_variable *tmpdebug = variable_named(var, "variable_name"); 00517 const struct ast_variable *tmpdebug2 = variable_named(var, "variable_value"); 00518 if (tmpdebug && tmpdebug2) { 00519 ast_debug(3, "LINE(%d) Added to vars - %s = %s\n", __LINE__, tmpdebug->value, tmpdebug2->value); 00520 } 00521 } 00522 vars[entry_index++] = var; 00523 prev = NULL; 00524 } 00525 00526 delim_count++; 00527 } while (delim_count <= delim_tot_count && static_table_config == table_config); 00528 00529 if (static_table_config != table_config) { 00530 ast_debug(3, "LINE(%d) Added to vars - non static\n", __LINE__); 00531 00532 vars[entry_index++] = var; 00533 prev = NULL; 00534 } 00535 ldap_entry = ldap_next_entry(ldapConn, ldap_entry); 00536 } /*!< end for loop over ldap_entry */ 00537 00538 return vars; 00539 }
static char * realtime_ldap_status | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 1754 of file res_config_ldap.c.
References ast_cli(), ast_strlen_zero(), base_distinguished_name, CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, connect_time, ast_cli_args::fd, ldapConn, status, url, and ast_cli_entry::usage.
01755 { 01756 char status[256], credentials[100] = ""; 01757 int ctimesec = time(NULL) - connect_time; 01758 01759 switch (cmd) { 01760 case CLI_INIT: 01761 e->command = "realtime show ldap status"; 01762 e->usage = 01763 "Usage: realtime show ldap status\n" 01764 " Shows connection information for the LDAP RealTime driver\n"; 01765 return NULL; 01766 case CLI_GENERATE: 01767 return NULL; 01768 } 01769 01770 if (!ldapConn) 01771 return CLI_FAILURE; 01772 01773 if (!ast_strlen_zero(url)) 01774 snprintf(status, sizeof(status), "Connected to '%s', baseDN %s", url, base_distinguished_name); 01775 01776 if (!ast_strlen_zero(user)) 01777 snprintf(credentials, sizeof(credentials), " with username %s", user); 01778 01779 if (ctimesec > 31536000) { 01780 ast_cli(a->fd, "%s%s for %d years, %d days, %d hours, %d minutes, %d seconds.\n", 01781 status, credentials, ctimesec / 31536000, 01782 (ctimesec % 31536000) / 86400, (ctimesec % 86400) / 3600, 01783 (ctimesec % 3600) / 60, ctimesec % 60); 01784 } else if (ctimesec > 86400) { 01785 ast_cli(a->fd, "%s%s for %d days, %d hours, %d minutes, %d seconds.\n", 01786 status, credentials, ctimesec / 86400, (ctimesec % 86400) / 3600, 01787 (ctimesec % 3600) / 60, ctimesec % 60); 01788 } else if (ctimesec > 3600) { 01789 ast_cli(a->fd, "%s%s for %d hours, %d minutes, %d seconds.\n", 01790 status, credentials, ctimesec / 3600, (ctimesec % 3600) / 60, 01791 ctimesec % 60); 01792 } else if (ctimesec > 60) { 01793 ast_cli(a->fd, "%s%s for %d minutes, %d seconds.\n", status, credentials, 01794 ctimesec / 60, ctimesec % 60); 01795 } else { 01796 ast_cli(a->fd, "%s%s for %d seconds.\n", status, credentials, ctimesec); 01797 } 01798 01799 return CLI_SUCCESS; 01800 }
static struct ast_config* realtime_multi_ldap | ( | const char * | basedn, | |
const char * | table_name, | |||
va_list | ap | |||
) | [static] |
See Asterisk doc.
this function will be called for the switch statment if no match is found with the realtime_ldap function(i.e. it is a failover); however, the ast_load_realtime wil match on wildcharacters also depending on what the mode is set to this is an area of asterisk that could do with a lot of modification I think this function returns Realtime dynamic objects
Definition at line 951 of file res_config_ldap.c.
References ast_category_append(), ast_category_new(), ast_category_rename(), ast_config_new(), ast_log(), ast_strdupa, ast_variable_append(), free, LOG_ERROR, LOG_WARNING, ast_variable::next, realtime_ldap_base_ap(), and var.
00953 { 00954 char *op; 00955 const char *initfield = NULL; 00956 const char *newparam, *newval; 00957 struct ast_variable **vars = 00958 realtime_ldap_base_ap(NULL, basedn, table_name, ap); 00959 struct ast_config *cfg = NULL; 00960 00961 newparam = va_arg(ap, const char *); 00962 newval = va_arg(ap, const char *); 00963 if (!newparam || !newval) { 00964 ast_log(LOG_WARNING, "realtime retrieval requires at least 1 parameter and 1 value to search on.\n"); 00965 return NULL; 00966 } 00967 initfield = ast_strdupa(newparam); 00968 if ((op = strchr(initfield, ' '))) { 00969 *op = '\0'; 00970 } 00971 00972 if (vars) { 00973 cfg = ast_config_new(); 00974 if (!cfg) { 00975 ast_log(LOG_ERROR, "Unable to create a config!\n"); 00976 } else { 00977 struct ast_variable **p = vars; 00978 00979 while (*p) { 00980 struct ast_category *cat = NULL; 00981 cat = ast_category_new("", table_name, -1); 00982 if (!cat) { 00983 ast_log(LOG_ERROR, "Unable to create a new category!\n"); 00984 break; 00985 } else { 00986 struct ast_variable *var = *p; 00987 while (var) { 00988 struct ast_variable *next = var->next; 00989 if (initfield && !strcmp(initfield, var->name)) { 00990 ast_category_rename(cat, var->value); 00991 } 00992 var->next = NULL; 00993 ast_variable_append(cat, var); 00994 var = next; 00995 } 00996 } 00997 ast_category_append(cfg, cat); 00998 p++; 00999 } 01000 } 01001 free(vars); 01002 } 01003 return cfg; 01004 01005 }
static int reload | ( | void | ) | [static] |
Definition at line 1578 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, and parse_config().
01579 { 01580 /* Aquire control before doing anything to the module itself. */ 01581 ast_mutex_lock(&ldap_lock); 01582 01583 if (ldapConn) { 01584 ldap_unbind_ext_s(ldapConn, NULL, NULL); 01585 ldapConn = NULL; 01586 } 01587 01588 if (parse_config() < 0) { 01589 ast_log(LOG_NOTICE, "Cannot reload LDAP RealTime driver.\n"); 01590 ast_mutex_unlock(&ldap_lock); 01591 return 0; 01592 } 01593 01594 if (!ldap_reconnect()) { 01595 ast_log(LOG_WARNING, "Couldn't establish connection to your directory server. Check debug.\n"); 01596 } 01597 01598 ast_verb(2, "LDAP RealTime driver reloaded.\n"); 01599 01600 /* Done reloading. Release lock so others can now use driver. */ 01601 ast_mutex_unlock(&ldap_lock); 01602 01603 return 0; 01604 }
static int replace_string_in_string | ( | char * | string, | |
const char * | search, | |||
const char * | by | |||
) | [static] |
Replace <search> by <by> in string.
Definition at line 668 of file res_config_ldap.c.
Referenced by append_var_and_value_to_filter().
00669 { 00670 int search_len = strlen(search); 00671 int by_len = strlen(by); 00672 int replaced = 0; 00673 char *p = strstr(string, search); 00674 00675 if (p) { 00676 replaced = 1; 00677 while (p) { 00678 if (by_len == search_len) { 00679 memcpy(p, by, by_len); 00680 } else { 00681 memmove(p + by_len, p + search_len, strlen(p + search_len) + 1); 00682 memcpy(p, by, by_len); 00683 } 00684 p = strstr(p + by_len, search); 00685 } 00686 } 00687 return replaced; 00688 }
static int semicolon_count_str | ( | const char * | somestr | ) | [static] |
for the semicolon delimiter
somestr | - pointer to a string |
Definition at line 152 of file res_config_ldap.c.
Referenced by realtime_ldap_result_to_vars(), and semicolon_count_var().
00153 { 00154 int count = 0; 00155 00156 for (; *somestr; somestr++) { 00157 if (*somestr == ';') 00158 count++; 00159 } 00160 00161 return count; 00162 }
static int semicolon_count_var | ( | struct ast_variable * | var | ) | [static] |
Definition at line 167 of file res_config_ldap.c.
References ast_debug, semicolon_count_str(), ast_variable::value, var, and variable_named().
Referenced by realtime_ldap_result_to_vars().
00168 { 00169 struct ast_variable *var_value = variable_named(var, "variable_value"); 00170 00171 if (!var_value) { 00172 return 0; 00173 } 00174 00175 ast_debug(2, "LINE(%d) semicolon_count_var: %s\n", __LINE__, var_value->value); 00176 00177 return semicolon_count_str(var_value->value); 00178 }
static char* substituted | ( | struct ast_channel * | channel, | |
const char * | string | |||
) | [static] |
Definition at line 626 of file res_config_ldap.c.
References ast_calloc, ast_debug, ast_strlen_zero(), MAXRESULT, and pbx_substitute_variables_helper().
Referenced by cleaned_basedn().
00627 { 00628 #define MAXRESULT 2048 00629 char *ret_string = NULL; 00630 00631 if (!ast_strlen_zero(string)) { 00632 ret_string = ast_calloc(1, MAXRESULT); 00633 pbx_substitute_variables_helper(channel, string, ret_string, MAXRESULT - 1); 00634 } 00635 ast_debug(2, "substituted: string: '%s' => '%s' \n", string, ret_string); 00636 return ret_string; 00637 }
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.
Definition at line 124 of file res_config_ldap.c.
References AST_LIST_TRAVERSE, ldap_table_config::entry, and ldap_table_config::table_name.
Referenced by parse_config(), realtime_ldap_base_ap(), update2_ldap(), and update_ldap().
00125 { 00126 struct ldap_table_config *c = NULL; 00127 00128 AST_LIST_TRAVERSE(&table_configs, c, entry) { 00129 if (!strcmp(c->table_name, table_name)) 00130 break; 00131 } 00132 00133 return c; 00134 }
static struct ldap_table_config* table_config_new | ( | const char * | table_name | ) | [static] |
Create a new table_config.
Definition at line 105 of file res_config_ldap.c.
References ast_calloc, ast_strdup, and free.
Referenced by parse_config().
00106 { 00107 struct ldap_table_config *p; 00108 00109 if (!(p = ast_calloc(1, sizeof(*p)))) 00110 return NULL; 00111 00112 if (table_name) { 00113 if (!(p->table_name = ast_strdup(table_name))) { 00114 free(p); 00115 return NULL; 00116 } 00117 } 00118 00119 return p; 00120 }
static void table_configs_free | ( | void | ) | [static] |
Free table_config.
Definition at line 202 of file res_config_ldap.c.
References ldap_table_config::additional_filter, ast_free, AST_LIST_REMOVE_HEAD, ast_variables_destroy(), ldap_table_config::attributes, base_table_config, ldap_table_config::entry, free, static_table_config, and ldap_table_config::table_name.
Referenced by parse_config(), and unload_module().
00203 { 00204 struct ldap_table_config *c; 00205 00206 while ((c = AST_LIST_REMOVE_HEAD(&table_configs, entry))) { 00207 if (c->table_name) { 00208 ast_free(c->table_name); 00209 } 00210 if (c->additional_filter) { 00211 ast_free(c->additional_filter); 00212 } 00213 if (c->attributes) { 00214 ast_variables_destroy(c->attributes); 00215 } 00216 free(c); 00217 } 00218 00219 base_table_config = NULL; 00220 static_table_config = NULL; 00221 }
static int unload_module | ( | void | ) | [static] |
Definition at line 1557 of file res_config_ldap.c.
References ARRAY_LEN, ast_cli_unregister_multiple(), ast_config_engine_deregister(), ast_mutex_lock, ast_mutex_unlock, ast_verb, ldap_cli, ldap_engine, ldap_lock, ldapConn, and table_configs_free().
01558 { 01559 /* Aquire control before doing anything to the module itself. */ 01560 ast_mutex_lock(&ldap_lock); 01561 01562 table_configs_free(); 01563 01564 if (ldapConn) { 01565 ldap_unbind_ext_s(ldapConn, NULL, NULL); 01566 ldapConn = NULL; 01567 } 01568 ast_cli_unregister_multiple(ldap_cli, ARRAY_LEN(ldap_cli)); 01569 ast_config_engine_deregister(&ldap_engine); 01570 ast_verb(1, "LDAP RealTime driver unloaded.\n"); 01571 01572 /* Unlock so something else can destroy the lock. */ 01573 ast_mutex_unlock(&ldap_lock); 01574 01575 return 0; 01576 }
static int update2_ldap | ( | const char * | basedn, | |
const char * | table_name, | |||
va_list | ap | |||
) | [static] |
Definition at line 1340 of file res_config_ldap.c.
References ldap_table_config::additional_filter, append_var_and_value_to_filter(), ast_calloc, ast_debug, ast_free, ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_realloc, ast_str_append(), ast_str_buffer(), ast_str_create(), base_table_config, cleaned_basedn(), convert_attribute_name_to_ldap(), filter(), is_ldap_connect_error(), ldap_lock, ldap_reconnect(), ldapConn, LOG_ERROR, LOG_WARNING, option_debug, and table_config_for_table_name().
01341 { 01342 int error = 0; 01343 LDAPMessage *ldap_entry = NULL; 01344 LDAPMod **ldap_mods; 01345 const char *newparam = NULL; 01346 const char *newval = NULL; 01347 char *dn; 01348 int num_entries = 0; 01349 int i = 0; 01350 int mods_size = 0; 01351 int mod_exists = 0; 01352 struct ldap_table_config *table_config = NULL; 01353 char *clean_basedn = NULL; 01354 struct ast_str *filter = NULL; 01355 int tries = 0; 01356 int result = 0; 01357 LDAPMessage *ldap_result_msg = NULL; 01358 01359 if (!table_name) { 01360 ast_log(LOG_ERROR, "No table_name specified.\n"); 01361 return -1; 01362 } 01363 01364 if (!(filter = ast_str_create(80))) { 01365 return -1; 01366 } 01367 01368 ast_mutex_lock(&ldap_lock); 01369 01370 /* We now have our complete statement; Lets connect to the server and execute it. */ 01371 if (!ldap_reconnect()) { 01372 ast_mutex_unlock(&ldap_lock); 01373 ast_free(filter); 01374 return -1; 01375 } 01376 01377 table_config = table_config_for_table_name(table_name); 01378 if (!table_config) { 01379 ast_log(LOG_ERROR, "No table named '%s'.\n", table_name); 01380 ast_mutex_unlock(&ldap_lock); 01381 ast_free(filter); 01382 return -1; 01383 } 01384 01385 clean_basedn = cleaned_basedn(NULL, basedn); 01386 01387 /* Create the filter with the table additional filter and the parameter/value pairs we were given */ 01388 ast_str_append(&filter, 0, "(&"); 01389 if (table_config && table_config->additional_filter) { 01390 ast_str_append(&filter, 0, "%s", table_config->additional_filter); 01391 } 01392 if (table_config != base_table_config && base_table_config 01393 && base_table_config->additional_filter) { 01394 ast_str_append(&filter, 0, "%s", base_table_config->additional_filter); 01395 } 01396 01397 /* Get multiple lookup keyfields and values */ 01398 while ((newparam = va_arg(ap, const char *))) { 01399 newval = va_arg(ap, const char *); 01400 append_var_and_value_to_filter(&filter, table_config, newparam, newval); 01401 } 01402 ast_str_append(&filter, 0, ")"); 01403 01404 /* Create the modification array with the parameter/value pairs we were given, 01405 * if there are several parameters with the same name, we collect them into 01406 * one parameter/value pair and delimit them with a semicolon */ 01407 newparam = va_arg(ap, const char *); 01408 newparam = convert_attribute_name_to_ldap(table_config, newparam); 01409 newval = va_arg(ap, const char *); 01410 if (!newparam || !newval) { 01411 ast_log(LOG_WARNING, "LINE(%d): need at least one parameter to modify.\n", __LINE__); 01412 ast_free(filter); 01413 ast_free(clean_basedn); 01414 return -1; 01415 } 01416 01417 mods_size = 2; /* one for the first param/value pair and one for the the terminating NULL */ 01418 ldap_mods = ast_calloc(sizeof(LDAPMod *), mods_size); 01419 ldap_mods[0] = ast_calloc(1, sizeof(LDAPMod)); 01420 01421 ldap_mods[0]->mod_op = LDAP_MOD_REPLACE; 01422 ldap_mods[0]->mod_type = ast_calloc(sizeof(char), strlen(newparam) + 1); 01423 strcpy(ldap_mods[0]->mod_type, newparam); 01424 01425 ldap_mods[0]->mod_values = ast_calloc(sizeof(char), 2); 01426 ldap_mods[0]->mod_values[0] = ast_calloc(sizeof(char), strlen(newval) + 1); 01427 strcpy(ldap_mods[0]->mod_values[0], newval); 01428 01429 while ((newparam = va_arg(ap, const char *))) { 01430 newparam = convert_attribute_name_to_ldap(table_config, newparam); 01431 newval = va_arg(ap, const char *); 01432 mod_exists = 0; 01433 01434 for (i = 0; i < mods_size - 1; i++) { 01435 if (ldap_mods[i]&& !strcmp(ldap_mods[i]->mod_type, newparam)) { 01436 /* We have the parameter allready, adding the value as a semicolon delimited value */ 01437 ldap_mods[i]->mod_values[0] = ast_realloc(ldap_mods[i]->mod_values[0], sizeof(char) * (strlen(ldap_mods[i]->mod_values[0]) + strlen(newval) + 2)); 01438 strcat(ldap_mods[i]->mod_values[0], ";"); 01439 strcat(ldap_mods[i]->mod_values[0], newval); 01440 mod_exists = 1; 01441 break; 01442 } 01443 } 01444 01445 /* create new mod */ 01446 if (!mod_exists) { 01447 mods_size++; 01448 ldap_mods = ast_realloc(ldap_mods, sizeof(LDAPMod *) * mods_size); 01449 ldap_mods[mods_size - 1] = NULL; 01450 ldap_mods[mods_size - 2] = ast_calloc(1, sizeof(LDAPMod)); 01451 01452 ldap_mods[mods_size - 2]->mod_op = LDAP_MOD_REPLACE; 01453 01454 ldap_mods[mods_size - 2]->mod_type = ast_calloc(sizeof(char), strlen(newparam) + 1); 01455 strcpy(ldap_mods[mods_size - 2]->mod_type, newparam); 01456 01457 ldap_mods[mods_size - 2]->mod_values = ast_calloc(sizeof(char *), 2); 01458 ldap_mods[mods_size - 2]->mod_values[0] = ast_calloc(sizeof(char), strlen(newval) + 1); 01459 strcpy(ldap_mods[mods_size - 2]->mod_values[0], newval); 01460 } 01461 } 01462 /* freeing ldap_mods further down */ 01463 01464 do { 01465 /* freeing ldap_result further down */ 01466 result = ldap_search_ext_s(ldapConn, clean_basedn, 01467 LDAP_SCOPE_SUBTREE, ast_str_buffer(filter), NULL, 0, NULL, NULL, NULL, LDAP_NO_LIMIT, 01468 &ldap_result_msg); 01469 if (result != LDAP_SUCCESS && is_ldap_connect_error(result)) { 01470 ast_log(LOG_WARNING, "Failed to query directory. Try %d/3\n", tries + 1); 01471 tries++; 01472 if (tries < 3) { 01473 usleep(500000L * tries); 01474 if (ldapConn) { 01475 ldap_unbind_ext_s(ldapConn, NULL, NULL); 01476 ldapConn = NULL; 01477 } 01478 if (!ldap_reconnect()) { 01479 break; 01480 } 01481 } 01482 } 01483 } while (result != LDAP_SUCCESS && tries < 3 && is_ldap_connect_error(result)); 01484 01485 if (result != LDAP_SUCCESS) { 01486 ast_log(LOG_WARNING, "Failed to query directory. Error: %s.\n", ldap_err2string(result)); 01487 ast_log(LOG_WARNING, "Query: %s\n", ast_str_buffer(filter)); 01488 01489 ast_mutex_unlock(&ldap_lock); 01490 ast_free(filter); 01491 ast_free(clean_basedn); 01492 ldap_msgfree(ldap_result_msg); 01493 ldap_mods_free(ldap_mods, 0); 01494 return -1; 01495 } 01496 /* Ready to update */ 01497 if ((num_entries = ldap_count_entries(ldapConn, ldap_result_msg)) > 0) { 01498 for (i = 0; option_debug > 2 && i < mods_size - 1; i++) { 01499 ast_debug(3, "LINE(%d) %s=%s \n", __LINE__, ldap_mods[i]->mod_type, ldap_mods[i]->mod_values[0]); 01500 } 01501 01502 ldap_entry = ldap_first_entry(ldapConn, ldap_result_msg); 01503 01504 for (i = 0; ldap_entry; i++) { 01505 dn = ldap_get_dn(ldapConn, ldap_entry); 01506 if ((error = ldap_modify_ext_s(ldapConn, dn, ldap_mods, NULL, NULL)) != LDAP_SUCCESS) { 01507 ast_log(LOG_ERROR, "Couldn't modify dn:%s because %s", dn, ldap_err2string(error)); 01508 } 01509 01510 ldap_entry = ldap_next_entry(ldapConn, ldap_entry); 01511 } 01512 } 01513 01514 ast_mutex_unlock(&ldap_lock); 01515 if (filter) { 01516 ast_free(filter); 01517 } 01518 if (clean_basedn) { 01519 ast_free(clean_basedn); 01520 } 01521 ldap_msgfree(ldap_result_msg); 01522 ldap_mods_free(ldap_mods, 0); 01523 return num_entries; 01524 }
static int update_ldap | ( | const char * | basedn, | |
const char * | table_name, | |||
const char * | attribute, | |||
const char * | lookup, | |||
va_list | ap | |||
) | [static] |
Definition at line 1156 of file res_config_ldap.c.
References ldap_table_config::additional_filter, append_var_and_value_to_filter(), ast_calloc, ast_debug, ast_free, ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_realloc, ast_str_append(), ast_str_buffer(), ast_str_create(), ast_strdup, base_table_config, cleaned_basedn(), convert_attribute_name_to_ldap(), filter(), free, is_ldap_connect_error(), ldap_lock, ldap_reconnect(), ldapConn, LOG_ERROR, LOG_WARNING, option_debug, and table_config_for_table_name().
01158 { 01159 int error = 0; 01160 LDAPMessage *ldap_entry = NULL; 01161 LDAPMod **ldap_mods; 01162 const char *newparam = NULL; 01163 const char *newval = NULL; 01164 char *dn; 01165 int num_entries = 0; 01166 int i = 0; 01167 int mods_size = 0; 01168 int mod_exists = 0; 01169 struct ldap_table_config *table_config = NULL; 01170 char *clean_basedn = NULL; 01171 struct ast_str *filter = NULL; 01172 int tries = 0; 01173 int result = 0; 01174 LDAPMessage *ldap_result_msg = NULL; 01175 01176 if (!table_name) { 01177 ast_log(LOG_ERROR, "No table_name specified.\n"); 01178 return -1; 01179 } 01180 01181 if (!(filter = ast_str_create(80))) { 01182 return -1; 01183 } 01184 01185 if (!attribute || !lookup) { 01186 ast_log(LOG_WARNING, "LINE(%d): search parameters are empty.\n", __LINE__); 01187 return -1; 01188 } 01189 ast_mutex_lock(&ldap_lock); 01190 01191 /* We now have our complete statement; Lets connect to the server and execute it. */ 01192 if (!ldap_reconnect()) { 01193 ast_mutex_unlock(&ldap_lock); 01194 return -1; 01195 } 01196 01197 table_config = table_config_for_table_name(table_name); 01198 if (!table_config) { 01199 ast_log(LOG_ERROR, "No table named '%s'.\n", table_name); 01200 ast_mutex_unlock(&ldap_lock); 01201 return -1; 01202 } 01203 01204 clean_basedn = cleaned_basedn(NULL, basedn); 01205 01206 /* Create the filter with the table additional filter and the parameter/value pairs we were given */ 01207 ast_str_append(&filter, 0, "(&"); 01208 if (table_config && table_config->additional_filter) { 01209 ast_str_append(&filter, 0, "%s", table_config->additional_filter); 01210 } 01211 if (table_config != base_table_config && base_table_config && base_table_config->additional_filter) { 01212 ast_str_append(&filter, 0, "%s", base_table_config->additional_filter); 01213 } 01214 append_var_and_value_to_filter(&filter, table_config, attribute, lookup); 01215 ast_str_append(&filter, 0, ")"); 01216 01217 /* Create the modification array with the parameter/value pairs we were given, 01218 * if there are several parameters with the same name, we collect them into 01219 * one parameter/value pair and delimit them with a semicolon */ 01220 newparam = va_arg(ap, const char *); 01221 newparam = convert_attribute_name_to_ldap(table_config, newparam); 01222 newval = va_arg(ap, const char *); 01223 if (!newparam || !newval) { 01224 ast_log(LOG_WARNING, "LINE(%d): need at least one parameter to modify.\n", __LINE__); 01225 return -1; 01226 } 01227 01228 mods_size = 2; /* one for the first param/value pair and one for the the terminating NULL */ 01229 ldap_mods = ast_calloc(sizeof(LDAPMod *), mods_size); 01230 ldap_mods[0] = ast_calloc(1, sizeof(LDAPMod)); 01231 01232 ldap_mods[0]->mod_op = LDAP_MOD_REPLACE; 01233 ldap_mods[0]->mod_type = ast_strdup(newparam); 01234 01235 ldap_mods[0]->mod_values = ast_calloc(sizeof(char *), 2); 01236 ldap_mods[0]->mod_values[0] = ast_strdup(newval); 01237 01238 while ((newparam = va_arg(ap, const char *))) { 01239 newparam = convert_attribute_name_to_ldap(table_config, newparam); 01240 newval = va_arg(ap, const char *); 01241 mod_exists = 0; 01242 01243 for (i = 0; i < mods_size - 1; i++) { 01244 if (ldap_mods[i]&& !strcmp(ldap_mods[i]->mod_type, newparam)) { 01245 /* We have the parameter allready, adding the value as a semicolon delimited value */ 01246 ldap_mods[i]->mod_values[0] = ast_realloc(ldap_mods[i]->mod_values[0], sizeof(char) * (strlen(ldap_mods[i]->mod_values[0]) + strlen(newval) + 2)); 01247 strcat(ldap_mods[i]->mod_values[0], ";"); 01248 strcat(ldap_mods[i]->mod_values[0], newval); 01249 mod_exists = 1; 01250 break; 01251 } 01252 } 01253 01254 /* create new mod */ 01255 if (!mod_exists) { 01256 mods_size++; 01257 ldap_mods = ast_realloc(ldap_mods, sizeof(LDAPMod *) * mods_size); 01258 ldap_mods[mods_size - 1] = NULL; 01259 01260 ldap_mods[mods_size - 2] = ast_calloc(1, sizeof(LDAPMod)); 01261 01262 ldap_mods[mods_size - 2]->mod_type = ast_calloc(sizeof(char), strlen(newparam) + 1); 01263 strcpy(ldap_mods[mods_size - 2]->mod_type, newparam); 01264 01265 if (strlen(newval) == 0) { 01266 ldap_mods[mods_size - 2]->mod_op = LDAP_MOD_DELETE; 01267 } else { 01268 ldap_mods[mods_size - 2]->mod_op = LDAP_MOD_REPLACE; 01269 01270 ldap_mods[mods_size - 2]->mod_values = ast_calloc(sizeof(char *), 2); 01271 ldap_mods[mods_size - 2]->mod_values[0] = ast_calloc(sizeof(char), strlen(newval) + 1); 01272 strcpy(ldap_mods[mods_size - 2]->mod_values[0], newval); 01273 } 01274 } 01275 } 01276 /* freeing ldap_mods further down */ 01277 01278 do { 01279 /* freeing ldap_result further down */ 01280 result = ldap_search_ext_s(ldapConn, clean_basedn, 01281 LDAP_SCOPE_SUBTREE, ast_str_buffer(filter), NULL, 0, NULL, NULL, NULL, LDAP_NO_LIMIT, 01282 &ldap_result_msg); 01283 if (result != LDAP_SUCCESS && is_ldap_connect_error(result)) { 01284 ast_log(LOG_WARNING, "Failed to query directory. Try %d/3\n", tries + 1); 01285 tries++; 01286 if (tries < 3) { 01287 usleep(500000L * tries); 01288 if (ldapConn) { 01289 ldap_unbind_ext_s(ldapConn, NULL, NULL); 01290 ldapConn = NULL; 01291 } 01292 if (!ldap_reconnect()) 01293 break; 01294 } 01295 } 01296 } while (result != LDAP_SUCCESS && tries < 3 && is_ldap_connect_error(result)); 01297 01298 if (result != LDAP_SUCCESS) { 01299 ast_log(LOG_WARNING, "Failed to query directory. Error: %s.\n", ldap_err2string(result)); 01300 ast_log(LOG_WARNING, "Query: %s\n", ast_str_buffer(filter)); 01301 01302 ast_mutex_unlock(&ldap_lock); 01303 free(filter); 01304 free(clean_basedn); 01305 ldap_msgfree(ldap_result_msg); 01306 ldap_mods_free(ldap_mods, 0); 01307 return -1; 01308 } 01309 /* Ready to update */ 01310 if ((num_entries = ldap_count_entries(ldapConn, ldap_result_msg)) > 0) { 01311 ast_debug(3, "LINE(%d) Modifying %s=%s hits: %d\n", __LINE__, attribute, lookup, num_entries); 01312 for (i = 0; option_debug > 2 && i < mods_size - 1; i++) { 01313 if (ldap_mods[i]->mod_op != LDAP_MOD_DELETE) { 01314 ast_debug(3, "LINE(%d) %s=%s \n", __LINE__, ldap_mods[i]->mod_type, ldap_mods[i]->mod_values[0]); 01315 } else { 01316 ast_debug(3, "LINE(%d) deleting %s \n", __LINE__, ldap_mods[i]->mod_type); 01317 } 01318 } 01319 ldap_entry = ldap_first_entry(ldapConn, ldap_result_msg); 01320 01321 for (i = 0; ldap_entry; i++) { 01322 dn = ldap_get_dn(ldapConn, ldap_entry); 01323 if ((error = ldap_modify_ext_s(ldapConn, dn, ldap_mods, NULL, NULL)) != LDAP_SUCCESS) { 01324 ast_log(LOG_ERROR, "Couldn't modify '%s'='%s', dn:%s because %s\n", 01325 attribute, lookup, dn, ldap_err2string(error)); 01326 } 01327 01328 ldap_entry = ldap_next_entry(ldapConn, ldap_entry); 01329 } 01330 } 01331 01332 ast_mutex_unlock(&ldap_lock); 01333 ast_free(filter); 01334 ast_free(clean_basedn); 01335 ldap_msgfree(ldap_result_msg); 01336 ldap_mods_free(ldap_mods, 0); 01337 return num_entries; 01338 }
static struct ast_variable* variable_named | ( | struct ast_variable * | var, | |
const char * | name | |||
) | [static] |
Find variable by name.
Definition at line 137 of file res_config_ldap.c.
References var.
Referenced by config_ldap(), realtime_ldap_result_to_vars(), and semicolon_count_var().
00138 { 00139 for (; var; var = var->next) { 00140 if (!strcasecmp(name, var->name)) 00141 break; 00142 } 00143 00144 return var; 00145 }
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 = "8586c2a7d357cb591cc3a6607a8f62d1" , .load = load_module, .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_REALTIME_DRIVER, } [static] |
Definition at line 1807 of file res_config_ldap.c.
struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 1807 of file res_config_ldap.c.
char base_distinguished_name[512] [static] |
Definition at line 69 of file res_config_ldap.c.
Referenced by parse_config(), and realtime_ldap_status().
struct ldap_table_config* base_table_config [static] |
Definition at line 97 of file res_config_ldap.c.
Referenced by convert_attribute_name_from_ldap(), convert_attribute_name_to_ldap(), parse_config(), realtime_ldap_base_ap(), table_configs_free(), update2_ldap(), and update_ldap().
time_t connect_time [static] |
Definition at line 71 of file res_config_ldap.c.
Referenced by handle_cli_realtime_pgsql_status(), ldap_reconnect(), pgsql_reconnect(), and realtime_ldap_status().
struct ast_cli_entry ldap_cli[] [static] |
Initial value:
{ { .handler = realtime_ldap_status , .summary = "Shows connection information for the LDAP RealTime driver" ,__VA_ARGS__ }, }
Definition at line 100 of file res_config_ldap.c.
Referenced by load_module(), and unload_module().
struct ast_config_engine ldap_engine [static] |
Definition at line 1526 of file res_config_ldap.c.
Referenced by load_module(), and unload_module().
ast_mutex_t ldap_lock = { { { NULL }, { 0 }, 0, { NULL }, { 0 }, {{{ 0 }}}, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP } , 1, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP } [static] |
Definition at line 63 of file res_config_ldap.c.
Referenced by ldap_loadentry(), load_module(), realtime_ldap_base_ap(), reload(), unload_module(), update2_ldap(), and update_ldap().
LDAP* ldapConn [static] |
Definition at line 65 of file res_config_ldap.c.
Referenced by ldap_loadentry(), ldap_reconnect(), realtime_ldap_base_ap(), realtime_ldap_entry_to_var(), realtime_ldap_result_to_vars(), realtime_ldap_status(), reload(), unload_module(), update2_ldap(), and update_ldap().
char pass[512] [static] |
Definition at line 68 of file res_config_ldap.c.
Referenced by __ast_dsp_call_progress(), __get_header(), ast_db_deltree(), ast_db_gettree(), build_transactions(), gtalk_create_candidates(), handle_cli_database_show(), handle_cli_database_showkey(), jingle_create_candidates(), ldap_reconnect(), login_exec(), and parse_config().
struct ldap_table_config* static_table_config [static] |
Definition at line 98 of file res_config_ldap.c.
Referenced by parse_config(), realtime_ldap_result_to_vars(), and table_configs_free().
char url[512] [static] |
Definition at line 66 of file res_config_ldap.c.
Referenced by acf_curl_helper(), caldav_load_calendar(), dial_exec_full(), ewscal_load_calendar(), exchangecal_load_calendar(), ical_load_calendar(), ldap_reconnect(), parse_config(), queue_exec(), realtime_ldap_status(), reqprep(), respprep(), sendurl_exec(), and sip_sendhtml().
char user[512] [static] |
Definition at line 67 of file res_config_ldap.c.
Referenced by action_meetmelist(), add_user_extension(), admin_exec(), authenticate(), authenticate_request(), authenticate_verify(), build_route(), build_user(), build_user_routes(), calltoken_required(), channel_admin_exec(), check_access(), conf_queue_dtmf(), conf_run(), delete_users(), find_user(), get_manager_by_name_locked(), handle_cli_iax2_prune_realtime(), handle_cli_iax2_show_users(), handle_showmanager(), handle_showmanagers(), iax2_destroy_helper(), manager_displayconnects(), meetmemute(), pp_each_extension_helper(), pp_each_user_helper(), prune_users(), requirecalltoken_mark_auto(), reset_volumes(), send_talking_event(), set_config(), set_listen_volume(), set_talk_volume(), set_user_talking(), tweak_listen_volume(), tweak_talk_volume(), unref_user(), user_add_provider_cb(), user_chan_cb(), user_cmp_cb(), user_delme_cb(), user_destructor(), user_hash_cb(), user_listen_voldown_cb(), user_listen_volup_cb(), user_max_cmp(), user_no_cmp(), user_ref(), user_reset_vol_cb(), user_set_kickme_cb(), user_set_muted_cb(), user_set_unmuted_cb(), user_talk_voldown_cb(), user_talk_volup_cb(), user_unref(), users_data_provider_get(), users_hash_fn(), vm_users_data_provider_get(), and vm_users_data_provider_get_helper().
int version [static] |
Definition at line 70 of file res_config_ldap.c.