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