#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_DEFAULT , .description = "LDAP realtime interface" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, .reload = reload, } |
| static struct ast_module_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 = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER ) |
| static LDAP * | ldapConn |
| static char | pass [50] |
| static struct ldap_table_config * | static_table_config |
| static char | url [512] |
| static char | user [512] |
| static int | version = 3 |
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 1785 of file res_config_ldap.c.
| static void __unreg_module | ( | void | ) | [static] |
Definition at line 1785 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 693 of file res_config_ldap.c.
References ast_debug, ast_str_append(), ast_strdupa, convert_attribute_name_to_ldap(), len(), and replace_string_in_string().
Referenced by realtime_ldap_base_ap(), update2_ldap(), and update_ldap().
00696 { 00697 char *new_name = NULL; 00698 char *new_value = NULL; 00699 char *like_pos = strstr(name, " LIKE"); 00700 00701 ast_debug(2, "name='%s' value='%s'\n", name, value); 00702 00703 if (like_pos) { 00704 int len = like_pos - name; 00705 00706 name = new_name = ast_strdupa(name); 00707 new_name[len] = '\0'; 00708 value = new_value = ast_strdupa(value); 00709 replace_string_in_string(new_value, "\\_", "_"); 00710 replace_string_in_string(new_value, "%", "*"); 00711 } 00712 00713 name = convert_attribute_name_to_ldap(table_config, name); 00714 00715 ast_str_append(filter, 0, "(%s=%s)", name, value); 00716 }
| static char* cleaned_basedn | ( | struct ast_channel * | channel, | |
| const char * | basedn | |||
| ) | [static] |
Definition at line 642 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().
00643 { 00644 char *cbasedn = NULL; 00645 if (basedn) { 00646 char *p = NULL; 00647 cbasedn = substituted(channel, basedn); 00648 if (*cbasedn == '"') { 00649 cbasedn++; 00650 if (!ast_strlen_zero(cbasedn)) { 00651 int len = strlen(cbasedn); 00652 if (cbasedn[len - 1] == '"') 00653 cbasedn[len - 1] = '\0'; 00654 00655 } 00656 } 00657 p = cbasedn; 00658 while (*p) { 00659 if (*p == '|') 00660 *p = ','; 00661 p++; 00662 } 00663 } 00664 ast_debug(2, "basedn: '%s' => '%s' \n", basedn, cbasedn); 00665 return cbasedn; 00666 }
| 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 1000 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().
01001 { 01002 const struct category_and_metric *as = a; 01003 const struct category_and_metric *bs = b; 01004 01005 if (as->metric < bs->metric) { 01006 return -1; 01007 } else if (as->metric > bs->metric) { 01008 return 1; 01009 } else if (as->metric == bs->metric && strcmp(as->name, bs->name) != 0) { 01010 return strcmp(as->name, bs->name); 01011 } 01012 /* if the metric and the category name is the same, we check the variable metric */ 01013 if (as->var_metric < bs->var_metric) { 01014 return -1; 01015 } else if (as->var_metric > bs->var_metric) { 01016 return 1; 01017 } 01018 01019 return 0; 01020 }
| static struct ast_config* config_ldap | ( | const char * | basedn, | |
| const char * | table_name, | |||
| const char * | file, | |||
| struct ast_config * | cfg, | |||
| struct ast_flags | config_flags, | |||
| const char * | sugg_incl, | |||
| const char * | who_asked | |||
| ) | [static, read] |
See Asterisk doc.
This is for Static Realtime (again: I think...)
load the configuration stuff for the .conf files called on a reload
Definition at line 1029 of file res_config_ldap.c.
References ast_calloc, ast_category_append(), ast_category_new(), ast_config_internal_load(), ast_debug, ast_free, ast_log(), ast_strlen_zero(), ast_variable_append(), ast_variable_new(), compare_categories(), LOG_ERROR, LOG_WARNING, category_and_metric::metric, name, category_and_metric::name, realtime_ldap_base(), RES_CONFIG_LDAP_CONF, ast_variable::value, category_and_metric::var_metric, category_and_metric::variable_name, variable_named(), and category_and_metric::variable_value.
01031 { 01032 unsigned int vars_count = 0; 01033 struct ast_variable **vars; 01034 int i = 0; 01035 struct ast_variable *new_v = NULL; 01036 struct ast_category *cur_cat = NULL; 01037 const char *last_category = NULL; 01038 int last_category_metric = 0; 01039 struct category_and_metric *categories; 01040 struct ast_variable **p; 01041 01042 if (ast_strlen_zero(file) || !strcasecmp(file, RES_CONFIG_LDAP_CONF)) { 01043 ast_log(LOG_ERROR, "Missing configuration file: %s. Can't configure myself.\n", RES_CONFIG_LDAP_CONF); 01044 return NULL; 01045 } 01046 01047 vars = realtime_ldap_base(&vars_count, basedn, table_name, "filename", file, "commented", "FALSE", NULL); 01048 01049 if (!vars) { 01050 ast_log(LOG_WARNING, "Could not find config '%s' in database.\n", file); 01051 return NULL; 01052 } 01053 01054 /*!\note Since the items come back in random order, they need to be sorted 01055 * first, and since the data could easily exceed stack size, this is 01056 * allocated from the heap. 01057 */ 01058 if (!(categories = ast_calloc(sizeof(*categories), vars_count))) { 01059 return NULL; 01060 } 01061 01062 for (vars_count = 0, p = vars; *p; p++) { 01063 struct ast_variable *category = variable_named(*p, "category"); 01064 struct ast_variable *cat_metric = variable_named(*p, "cat_metric"); 01065 struct ast_variable *var_name = variable_named(*p, "variable_name"); 01066 struct ast_variable *var_val = variable_named(*p, "variable_value"); 01067 struct ast_variable *var_metric = variable_named(*p, "var_metric"); 01068 struct ast_variable *dn = variable_named(*p, "dn"); 01069 01070 ast_debug(3, "category: %s\n", category->value); 01071 ast_debug(3, "var_name: %s\n", var_name->value); 01072 ast_debug(3, "var_val: %s\n", var_val->value); 01073 ast_debug(3, "cat_metric: %s\n", cat_metric->value); 01074 01075 if (!category) { 01076 ast_log(LOG_ERROR, "No category name in entry '%s' for file '%s'.\n", 01077 (dn ? dn->value : "?"), file); 01078 } else if (!cat_metric) { 01079 ast_log(LOG_ERROR, "No category metric in entry '%s'(category: %s) for file '%s'.\n", 01080 (dn ? dn->value : "?"), category->value, file); 01081 } else if (!var_metric) { 01082 ast_log(LOG_ERROR, "No variable metric in entry '%s'(category: %s) for file '%s'.\n", 01083 (dn ? dn->value : "?"), category->value, file); 01084 } else if (!var_name) { 01085 ast_log(LOG_ERROR, "No variable name in entry '%s' (category: %s metric: %s) for file '%s'.\n", 01086 (dn ? dn->value : "?"), category->value, 01087 cat_metric->value, file); 01088 } else if (!var_val) { 01089 ast_log(LOG_ERROR, "No variable value in entry '%s' (category: %s metric: %s variable: %s) for file '%s'.\n", 01090 (dn ? dn->value : "?"), category->value, 01091 cat_metric->value, var_name->value, file); 01092 } else { 01093 categories[vars_count].name = category->value; 01094 categories[vars_count].metric = atoi(cat_metric->value); 01095 categories[vars_count].variable_name = var_name->value; 01096 categories[vars_count].variable_value = var_val->value; 01097 categories[vars_count].var_metric = atoi(var_metric->value); 01098 vars_count++; 01099 } 01100 } 01101 01102 qsort(categories, vars_count, sizeof(*categories), compare_categories); 01103 01104 for (i = 0; i < vars_count; i++) { 01105 if (!strcmp(categories[i].variable_name, "#include")) { 01106 struct ast_flags flags = { 0 }; 01107 if (!ast_config_internal_load(categories[i].variable_value, cfg, flags, "", who_asked)) { 01108 break; 01109 } 01110 continue; 01111 } 01112 01113 if (!last_category || strcmp(last_category, categories[i].name) || 01114 last_category_metric != categories[i].metric) { 01115 01116 cur_cat = ast_category_new(categories[i].name, table_name, -1); 01117 if (!cur_cat) { 01118 break; 01119 } 01120 last_category = categories[i].name; 01121 last_category_metric = categories[i].metric; 01122 ast_category_append(cfg, cur_cat); 01123 } 01124 01125 if (!(new_v = ast_variable_new(categories[i].variable_name, categories[i].variable_value, table_name))) { 01126 break; 01127 } 01128 01129 ast_variable_append(cur_cat, new_v); 01130 } 01131 01132 ast_free(vars); 01133 ast_free(categories); 01134 01135 return cfg; 01136 }
| 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, ast_variable::name, ast_variable::next, and ast_variable::value.
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, ast_variable::name, ast_variable::next, 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 545 of file res_config_ldap.c.
Referenced by ldap_loadentry(), realtime_ldap_base_ap(), update2_ldap(), and update_ldap().
00546 { 00547 return (err == LDAP_SERVER_DOWN || err == LDAP_TIMEOUT || err == LDAP_CONNECT_ERROR); 00548 }
| static struct ast_variable* ldap_loadentry | ( | struct ldap_table_config * | table_config, | |
| const char * | dn | |||
| ) | [static, read] |
Get LDAP entry by dn and return attributes as variables - Should be locked before using it This is used for setting the default values of an object(i.e., with accountBaseDN).
< not using this
Definition at line 553 of file res_config_ldap.c.
References ast_debug, ast_log(), ast_mutex_unlock(), ast_realloc, ast_variables_destroy(), is_ldap_connect_error(), ldap_lock, ldap_reconnect(), LOG_ERROR, LOG_NOTICE, LOG_WARNING, realtime_ldap_result_to_vars(), and var.
Referenced by realtime_ldap_base_ap().
00555 { 00556 if (!table_config) { 00557 ast_log(LOG_ERROR, "No table config\n"); 00558 return NULL; 00559 } else { 00560 struct ast_variable **vars = NULL; 00561 struct ast_variable *var = NULL; 00562 int result = -1; 00563 LDAPMessage *ldap_result_msg = NULL; 00564 int tries = 0; 00565 00566 ast_debug(2, "ldap_loadentry dn=%s\n", dn); 00567 00568 do { 00569 result = ldap_search_ext_s(ldapConn, dn, LDAP_SCOPE_BASE, 00570 "(objectclass=*)", NULL, 0, NULL, NULL, NULL, LDAP_NO_LIMIT, &ldap_result_msg); 00571 if (result != LDAP_SUCCESS && is_ldap_connect_error(result)) { 00572 ast_log(LOG_WARNING, "Failed to query database. Try %d/3\n", tries + 1); 00573 tries++; 00574 if (tries < 3) { 00575 usleep(500000L * tries); 00576 if (ldapConn) { 00577 ldap_unbind_ext_s(ldapConn, NULL, NULL); 00578 ldapConn = NULL; 00579 } 00580 if (!ldap_reconnect()) { 00581 break; 00582 } 00583 } 00584 } 00585 } while (result != LDAP_SUCCESS && tries < 3 && is_ldap_connect_error(result)); 00586 00587 if (result != LDAP_SUCCESS) { 00588 ast_log(LOG_WARNING, "Failed to query database. Error: %s.\n", ldap_err2string(result)); 00589 ast_debug(2, "dn=%s\n", dn); 00590 ast_mutex_unlock(&ldap_lock); 00591 return NULL; 00592 } else { 00593 int num_entry = 0; 00594 unsigned int *entries_count_ptr = NULL; /*!< not using this */ 00595 00596 if ((num_entry = ldap_count_entries(ldapConn, ldap_result_msg)) > 0) { 00597 ast_debug(3, "num_entry: %d\n", num_entry); 00598 00599 vars = realtime_ldap_result_to_vars(table_config, ldap_result_msg, entries_count_ptr); 00600 if (num_entry > 1) { 00601 ast_log(LOG_NOTICE, "More than one entry for dn=%s. Take only 1st one\n", dn); 00602 } 00603 } else { 00604 ast_debug(2, "Could not find any entry dn=%s.\n", dn); 00605 } 00606 } 00607 ldap_msgfree(ldap_result_msg); 00608 00609 /* Chopping \a vars down to one variable */ 00610 if (vars != NULL) { 00611 struct ast_variable **p = vars; 00612 p++; 00613 var = *p; 00614 while (var) { 00615 ast_variables_destroy(var); 00616 p++; 00617 } 00618 vars = ast_realloc(vars, sizeof(struct ast_variable *)); 00619 } 00620 00621 var = *vars; 00622 00623 return var; 00624 } 00625 }
| static int ldap_reconnect | ( | void | ) | [static] |
Definition at line 1686 of file res_config_ldap.c.
References ast_debug, ast_log(), ast_strlen_zero(), LOG_ERROR, and LOG_WARNING.
Referenced by ldap_loadentry(), load_module(), realtime_ldap_base_ap(), reload(), update2_ldap(), and update_ldap().
01687 { 01688 int bind_result = 0; 01689 struct berval cred; 01690 01691 if (ldapConn) { 01692 ast_debug(2, "Everything seems fine.\n"); 01693 return 1; 01694 } 01695 01696 if (ast_strlen_zero(url)) { 01697 ast_log(LOG_ERROR, "Not enough parameters to connect to ldap database\n"); 01698 return 0; 01699 } 01700 01701 if (LDAP_SUCCESS != ldap_initialize(&ldapConn, url)) { 01702 ast_log(LOG_ERROR, "Failed to init ldap connection to '%s'. Check debug for more info.\n", url); 01703 return 0; 01704 } 01705 01706 if (LDAP_OPT_SUCCESS != ldap_set_option(ldapConn, LDAP_OPT_PROTOCOL_VERSION, &version)) { 01707 ast_log(LOG_WARNING, "Unable to set LDAP protocol version to %d, falling back to default.\n", version); 01708 } 01709 01710 if (!ast_strlen_zero(user)) { 01711 ast_debug(2, "bind to '%s' as user '%s'\n", url, user); 01712 cred.bv_val = (char *) pass; 01713 cred.bv_len = strlen(pass); 01714 bind_result = ldap_sasl_bind_s(ldapConn, user, LDAP_SASL_SIMPLE, &cred, NULL, NULL, NULL); 01715 } else { 01716 ast_debug(2, "bind %s anonymously\n", url); 01717 cred.bv_val = NULL; 01718 cred.bv_len = 0; 01719 bind_result = ldap_sasl_bind_s(ldapConn, NULL, LDAP_SASL_SIMPLE, &cred, NULL, NULL, NULL); 01720 } 01721 if (bind_result == LDAP_SUCCESS) { 01722 ast_debug(2, "Successfully connected to database.\n"); 01723 connect_time = time(NULL); 01724 return 1; 01725 } else { 01726 ast_log(LOG_WARNING, "bind failed: %s\n", ldap_err2string(bind_result)); 01727 ldap_unbind_ext_s(ldapConn, NULL, NULL); 01728 ldapConn = NULL; 01729 return 0; 01730 } 01731 }
| 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, ast_variable::next, 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 1520 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().
01521 { 01522 if (parse_config() < 0) { 01523 ast_log(LOG_ERROR, "Cannot load LDAP RealTime driver.\n"); 01524 return 0; 01525 } 01526 01527 ast_mutex_lock(&ldap_lock); 01528 01529 if (!ldap_reconnect()) { 01530 ast_log(LOG_WARNING, "Couldn't establish connection to LDAP directory. Check debug.\n"); 01531 } 01532 01533 ast_config_engine_register(&ldap_engine); 01534 ast_verb(1, "LDAP RealTime driver loaded.\n"); 01535 ast_cli_register_multiple(ldap_cli, ARRAY_LEN(ldap_cli)); 01536 01537 ast_mutex_unlock(&ldap_lock); 01538 01539 return 0; 01540 }
| static int parse_config | ( | void | ) | [static] |
parse the configuration file
< using the [config] context for Static RealTime
Definition at line 1592 of file res_config_ldap.c.
References ldap_table_config::additional_filter, ast_category_browse(), ast_config_destroy(), ast_config_load, ast_copy_string(), AST_LIST_INSERT_HEAD, ast_log(), ast_strdup, ast_strlen_zero(), ast_variable_browse(), ast_variable_retrieve(), base_table_config, config, CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEMISSING, ldap_table_config::entry, ldap_table_config_add_attribute(), LOG_ERROR, LOG_NOTICE, LOG_WARNING, ast_variable::name, ast_variable::next, RES_CONFIG_LDAP_CONF, RES_CONFIG_LDAP_DEFAULT_BASEDN, s, static_table_config, table_config_for_table_name(), table_config_new(), table_configs_free(), ast_variable::value, and var.
01593 { 01594 struct ast_config *config; 01595 struct ast_flags config_flags = {0}; 01596 const char *s, *host; 01597 int port; 01598 char *category_name = NULL; 01599 01600 config = ast_config_load(RES_CONFIG_LDAP_CONF, config_flags); 01601 if (config == CONFIG_STATUS_FILEMISSING || config == CONFIG_STATUS_FILEINVALID) { 01602 ast_log(LOG_ERROR, "Cannot load configuration file: %s\n", RES_CONFIG_LDAP_CONF); 01603 return -1; 01604 } 01605 01606 if (!(s = ast_variable_retrieve(config, "_general", "user"))) { 01607 ast_log(LOG_NOTICE, "No directory user found, anonymous binding as default.\n"); 01608 user[0] = '\0'; 01609 } else { 01610 ast_copy_string(user, s, sizeof(user)); 01611 } 01612 01613 if (!ast_strlen_zero(user)) { 01614 if (!(s = ast_variable_retrieve(config, "_general", "pass"))) { 01615 ast_log(LOG_WARNING, "No directory password found, using 'asterisk' as default.\n"); 01616 ast_copy_string(pass, "asterisk", sizeof(pass)); 01617 } else { 01618 ast_copy_string(pass, s, sizeof(pass)); 01619 } 01620 } 01621 01622 /* URL is preferred, use host and port if not found */ 01623 if ((s = ast_variable_retrieve(config, "_general", "url"))) { 01624 ast_copy_string(url, s, sizeof(url)); 01625 } else if ((host = ast_variable_retrieve(config, "_general", "host"))) { 01626 if (!(s = ast_variable_retrieve(config, "_general", "port")) || sscanf(s, "%5d", &port) != 1 || port > 65535) { 01627 ast_log(LOG_NOTICE, "No directory port found, using 389 as default.\n"); 01628 port = 389; 01629 } 01630 01631 snprintf(url, sizeof(url), "ldap://%s:%d", host, port); 01632 } else { 01633 ast_log(LOG_ERROR, "No directory URL or host found.\n"); 01634 ast_config_destroy(config); 01635 return -1; 01636 } 01637 01638 if (!(s = ast_variable_retrieve(config, "_general", "basedn"))) { 01639 ast_log(LOG_ERROR, "No LDAP base dn found, using '%s' as default.\n", RES_CONFIG_LDAP_DEFAULT_BASEDN); 01640 ast_copy_string(base_distinguished_name, RES_CONFIG_LDAP_DEFAULT_BASEDN, sizeof(base_distinguished_name)); 01641 } else 01642 ast_copy_string(base_distinguished_name, s, sizeof(base_distinguished_name)); 01643 01644 if (!(s = ast_variable_retrieve(config, "_general", "version")) && !(s = ast_variable_retrieve(config, "_general", "protocol"))) { 01645 ast_log(LOG_NOTICE, "No explicit LDAP version found, using 3 as default.\n"); 01646 version = 3; 01647 } else if (sscanf(s, "%30d", &version) != 1 || version < 1 || version > 6) { 01648 ast_log(LOG_WARNING, "Invalid LDAP version '%s', using 3 as default.\n", s); 01649 version = 3; 01650 } 01651 01652 table_configs_free(); 01653 01654 while ((category_name = ast_category_browse(config, category_name))) { 01655 int is_general = (strcasecmp(category_name, "_general") == 0); 01656 int is_config = (strcasecmp(category_name, "config") == 0); /*!< using the [config] context for Static RealTime */ 01657 struct ast_variable *var = ast_variable_browse(config, category_name); 01658 01659 if (var) { 01660 struct ldap_table_config *table_config = 01661 table_config_for_table_name(category_name); 01662 if (!table_config) { 01663 table_config = table_config_new(category_name); 01664 AST_LIST_INSERT_HEAD(&table_configs, table_config, entry); 01665 if (is_general) 01666 base_table_config = table_config; 01667 if (is_config) 01668 static_table_config = table_config; 01669 } 01670 for (; var; var = var->next) { 01671 if (!strcasecmp(var->name, "additionalFilter")) { 01672 table_config->additional_filter = ast_strdup(var->value); 01673 } else { 01674 ldap_table_config_add_attribute(table_config, var->name, var->value); 01675 } 01676 } 01677 } 01678 } 01679 01680 ast_config_destroy(config); 01681 01682 return 1; 01683 }
| static struct ast_variable* realtime_ldap | ( | const char * | basedn, | |
| const char * | table_name, | |||
| va_list | ap | |||
| ) | [static, read] |
See Asterisk doc.
For Realtime Dynamic(i.e., switch, queues, and directory) -- I think
Definition at line 920 of file res_config_ldap.c.
References free, ast_variable::next, realtime_ldap_base_ap(), and var.
00922 { 00923 struct ast_variable **vars = realtime_ldap_base_ap(NULL, basedn, table_name, ap); 00924 struct ast_variable *var = NULL; 00925 00926 if (vars) { 00927 struct ast_variable *last_var = NULL; 00928 struct ast_variable **p = vars; 00929 while (*p) { 00930 if (last_var) { 00931 while (last_var->next) { 00932 last_var = last_var->next; 00933 } 00934 last_var->next = *p; 00935 } else { 00936 var = *p; 00937 last_var = var; 00938 } 00939 p++; 00940 } 00941 free(vars); 00942 } 00943 return var; 00944 }
| static struct ast_variable** realtime_ldap_base | ( | unsigned int * | entries_count_ptr, | |
| const char * | basedn, | |||
| const char * | table_name, | |||
| ... | ||||
| ) | [static, read] |
same as realtime_ldap_base_ap but take variable arguments count list
Definition at line 903 of file res_config_ldap.c.
References realtime_ldap_base_ap().
Referenced by config_ldap().
00905 { 00906 struct ast_variable **vars = NULL; 00907 va_list ap; 00908 00909 va_start(ap, table_name); 00910 vars = realtime_ldap_base_ap(entries_count_ptr, basedn, table_name, ap); 00911 va_end(ap); 00912 00913 return vars; 00914 }
| static struct ast_variable** realtime_ldap_base_ap | ( | unsigned int * | entries_count_ptr, | |
| const char * | basedn, | |||
| const char * | table_name, | |||
| va_list | ap | |||
| ) | [static, read] |
LDAP base function.
| 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 726 of file res_config_ldap.c.
References ldap_table_config::additional_filter, append_var_and_value_to_filter(), ast_debug, ast_free, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_str_append(), ast_str_buffer(), ast_str_create(), ast_variables_destroy(), base_table_config, cleaned_basedn(), filter(), is_ldap_connect_error(), ldap_loadentry(), ldap_lock, ldap_reconnect(), LOG_DEBUG, LOG_ERROR, LOG_WARNING, ast_variable::name, ast_variable::next, ldap_table_config::next, realtime_ldap_result_to_vars(), table_config_for_table_name(), and ast_variable::value.
Referenced by realtime_ldap(), realtime_ldap_base(), and realtime_multi_ldap().
00728 { 00729 struct ast_variable **vars = NULL; 00730 const char *newparam = NULL; 00731 const char *newval = NULL; 00732 struct ldap_table_config *table_config = NULL; 00733 char *clean_basedn = cleaned_basedn(NULL, basedn); 00734 struct ast_str *filter = NULL; 00735 int tries = 0; 00736 int result = 0; 00737 LDAPMessage *ldap_result_msg = NULL; 00738 00739 if (!table_name) { 00740 ast_log(LOG_ERROR, "No table_name specified.\n"); 00741 ast_free(clean_basedn); 00742 return NULL; 00743 } 00744 00745 if (!(filter = ast_str_create(80))) { 00746 ast_log(LOG_ERROR, "Can't initialize data structures.n"); 00747 ast_free(clean_basedn); 00748 return NULL; 00749 } 00750 00751 /* Get the first parameter and first value in our list of passed paramater/value pairs */ 00752 newparam = va_arg(ap, const char *); 00753 newval = va_arg(ap, const char *); 00754 00755 if (!newparam || !newval) { 00756 ast_log(LOG_ERROR, "Realtime retrieval requires at least 1 parameter" 00757 " and 1 value to search on.\n"); 00758 ast_free(filter); 00759 ast_free(clean_basedn); 00760 return NULL; 00761 } 00762 00763 ast_mutex_lock(&ldap_lock); 00764 00765 /* We now have our complete statement; Lets connect to the server and execute it. */ 00766 if (!ldap_reconnect()) { 00767 ast_mutex_unlock(&ldap_lock); 00768 ast_free(filter); 00769 ast_free(clean_basedn); 00770 return NULL; 00771 } 00772 00773 table_config = table_config_for_table_name(table_name); 00774 if (!table_config) { 00775 ast_log(LOG_WARNING, "No table named '%s'.\n", table_name); 00776 ast_mutex_unlock(&ldap_lock); 00777 ast_free(filter); 00778 ast_free(clean_basedn); 00779 return NULL; 00780 } 00781 00782 ast_str_append(&filter, 0, "(&"); 00783 00784 if (table_config && table_config->additional_filter) { 00785 ast_str_append(&filter, 0, "%s", table_config->additional_filter); 00786 } 00787 if (table_config != base_table_config && base_table_config && 00788 base_table_config->additional_filter) { 00789 ast_str_append(&filter, 0, "%s", base_table_config->additional_filter); 00790 } 00791 00792 /* Create the first part of the query using the first parameter/value pairs we just extracted */ 00793 /* If there is only 1 set, then we have our query. Otherwise, loop thru the list and concat */ 00794 00795 append_var_and_value_to_filter(&filter, table_config, newparam, newval); 00796 while ((newparam = va_arg(ap, const char *))) { 00797 newval = va_arg(ap, const char *); 00798 append_var_and_value_to_filter(&filter, table_config, newparam, newval); 00799 } 00800 ast_str_append(&filter, 0, ")"); 00801 00802 do { 00803 /* freeing ldap_result further down */ 00804 result = ldap_search_ext_s(ldapConn, clean_basedn, 00805 LDAP_SCOPE_SUBTREE, ast_str_buffer(filter), NULL, 0, NULL, NULL, NULL, LDAP_NO_LIMIT, 00806 &ldap_result_msg); 00807 if (result != LDAP_SUCCESS && is_ldap_connect_error(result)) { 00808 ast_log(LOG_DEBUG, "Failed to query database. Try %d/10\n", tries + 1); 00809 if (++tries < 10) { 00810 usleep(1); 00811 if (ldapConn) { 00812 ldap_unbind_ext_s(ldapConn, NULL, NULL); 00813 ldapConn = NULL; 00814 } 00815 if (!ldap_reconnect()) { 00816 break; 00817 } 00818 } 00819 } 00820 } while (result != LDAP_SUCCESS && tries < 10 && is_ldap_connect_error(result)); 00821 00822 if (result != LDAP_SUCCESS) { 00823 ast_log(LOG_WARNING, "Failed to query database. Error: %s.\n", ldap_err2string(result)); 00824 ast_log(LOG_WARNING, "Query: %s\n", ast_str_buffer(filter)); 00825 } else { 00826 /* this is where we create the variables from the search result 00827 * freeing this \a vars outside this function */ 00828 if (ldap_count_entries(ldapConn, ldap_result_msg) > 0) { 00829 /* is this a static var or some other? they are handled different for delimited values */ 00830 vars = realtime_ldap_result_to_vars(table_config, ldap_result_msg, entries_count_ptr); 00831 } else { 00832 ast_debug(1, "Could not find any entry matching %s in base dn %s.\n", ast_str_buffer(filter), clean_basedn); 00833 } 00834 00835 ldap_msgfree(ldap_result_msg); 00836 00837 /* TODO: get the default variables from the accountBaseDN, not implemented with delimited values */ 00838 if (vars) { 00839 struct ast_variable **p = vars; 00840 while (*p) { 00841 struct ast_variable *append_var = NULL; 00842 struct ast_variable *tmp = *p; 00843 while (tmp) { 00844 if (strcasecmp(tmp->name, "accountBaseDN") == 0) { 00845 /* Get the variable to compare with for the defaults */ 00846 struct ast_variable *base_var = ldap_loadentry(table_config, tmp->value); 00847 00848 while (base_var) { 00849 struct ast_variable *next = base_var->next; 00850 struct ast_variable *test_var = *p; 00851 int base_var_found = 0; 00852 00853 /* run throught the default values and fill it inn if it is missing */ 00854 while (test_var) { 00855 if (strcasecmp(test_var->name, base_var->name) == 0) { 00856 base_var_found = 1; 00857 break; 00858 } else { 00859 test_var = test_var->next; 00860 } 00861 } 00862 if (base_var_found) { 00863 base_var->next = NULL; 00864 ast_variables_destroy(base_var); 00865 base_var = next; 00866 } else { 00867 if (append_var) { 00868 base_var->next = append_var; 00869 } else { 00870 base_var->next = NULL; 00871 } 00872 append_var = base_var; 00873 base_var = next; 00874 } 00875 } 00876 } 00877 if (!tmp->next && append_var) { 00878 tmp->next = append_var; 00879 tmp = NULL; 00880 } else { 00881 tmp = tmp->next; 00882 } 00883 } 00884 p++; 00885 } 00886 } 00887 } 00888 00889 if (filter) { 00890 ast_free(filter); 00891 } 00892 00893 if (clean_basedn) { 00894 ast_free(clean_basedn); 00895 } 00896 00897 ast_mutex_unlock(&ldap_lock); 00898 00899 return vars; 00900 }
| static struct ast_variable* realtime_ldap_entry_to_var | ( | struct ldap_table_config * | table_config, | |
| LDAPMessage * | ldap_entry | |||
| ) | [static, read] |
Get variables from ldap entry attributes.
Definition at line 278 of file res_config_ldap.c.
References ast_debug, ast_strlen_zero(), ast_variable_new(), convert_attribute_name_from_ldap(), ast_variable::next, ldap_table_config::table_name, value, and var.
Referenced by realtime_ldap_result_to_vars().
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 } else { 00310 valptr = NULL; 00311 } 00312 ast_debug(2, "md5: %s\n", valptr); 00313 } 00314 if (valptr) { 00315 /* ok, so looping through all delimited values except the last one (not, last character is not delimited...) */ 00316 if (is_delimited) { 00317 i = 0; 00318 pos = 0; 00319 while (!ast_strlen_zero(valptr + i)) { 00320 if (valptr[i] == ';') { 00321 valptr[i] = '\0'; 00322 if (prev) { 00323 prev->next = ast_variable_new(attribute_name, &valptr[pos], table_config->table_name); 00324 if (prev->next) { 00325 prev = prev->next; 00326 } 00327 } else { 00328 prev = var = ast_variable_new(attribute_name, &valptr[pos], table_config->table_name); 00329 } 00330 pos = i + 1; 00331 } 00332 i++; 00333 } 00334 } 00335 /* for the last delimited value or if the value is not delimited: */ 00336 if (prev) { 00337 prev->next = ast_variable_new(attribute_name, &valptr[pos], table_config->table_name); 00338 if (prev->next) { 00339 prev = prev->next; 00340 } 00341 } else { 00342 prev = var = ast_variable_new(attribute_name, &valptr[pos], table_config->table_name); 00343 } 00344 } 00345 } 00346 ldap_value_free_len(values); 00347 } 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, read] |
Get variables from ldap entry attributes - Should be locked before using it.
The results are freed outside this function so is the vars array.
Definition at line 361 of file res_config_ldap.c.
References ast_calloc, ast_debug, ast_strdup, ast_strlen_zero(), ast_variable_new(), convert_attribute_name_from_ldap(), free, ast_variable::next, option_debug, realtime_ldap_entry_to_var(), semicolon_count_str(), semicolon_count_var(), static_table_config, ldap_table_config::table_name, ast_variable::value, 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 tot_count += semicolon_count_var(realtime_ldap_entry_to_var(table_config, ldap_entry)); 00382 ldap_entry = ldap_next_entry(ldapConn, ldap_entry); 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 } else { 00430 valptr = NULL; 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_attribute_name = ldap_next_attribute(ldapConn, ldap_entry, ber); 00514 } /*!< while (ldap_attribute_name) */ 00515 ber_free(ber, 0); 00516 if (static_table_config == table_config) { 00517 if (option_debug > 2) { 00518 const struct ast_variable *tmpdebug = variable_named(var, "variable_name"); 00519 const struct ast_variable *tmpdebug2 = variable_named(var, "variable_value"); 00520 if (tmpdebug && tmpdebug2) { 00521 ast_debug(3, "LINE(%d) Added to vars - %s = %s\n", __LINE__, tmpdebug->value, tmpdebug2->value); 00522 } 00523 } 00524 vars[entry_index++] = var; 00525 prev = NULL; 00526 } 00527 00528 delim_count++; 00529 } while (delim_count <= delim_tot_count && static_table_config == table_config); 00530 00531 if (static_table_config != table_config) { 00532 ast_debug(3, "LINE(%d) Added to vars - non static\n", __LINE__); 00533 00534 vars[entry_index++] = var; 00535 prev = NULL; 00536 } 00537 ldap_entry = ldap_next_entry(ldapConn, ldap_entry); 00538 } /*!< end for loop over ldap_entry */ 00539 00540 return vars; 00541 }
| static char * realtime_ldap_status | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 1733 of file res_config_ldap.c.
References ast_cli(), ast_strlen_zero(), CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, status, and ast_cli_entry::usage.
01734 { 01735 char status[256], credentials[100] = ""; 01736 int ctimesec = time(NULL) - connect_time; 01737 01738 switch (cmd) { 01739 case CLI_INIT: 01740 e->command = "realtime show ldap status"; 01741 e->usage = 01742 "Usage: realtime show ldap status\n" 01743 " Shows connection information for the LDAP RealTime driver\n"; 01744 return NULL; 01745 case CLI_GENERATE: 01746 return NULL; 01747 } 01748 01749 if (!ldapConn) 01750 return CLI_FAILURE; 01751 01752 if (!ast_strlen_zero(url)) 01753 snprintf(status, sizeof(status), "Connected to '%s', baseDN %s", url, base_distinguished_name); 01754 01755 if (!ast_strlen_zero(user)) 01756 snprintf(credentials, sizeof(credentials), " with username %s", user); 01757 01758 if (ctimesec > 31536000) { 01759 ast_cli(a->fd, "%s%s for %d years, %d days, %d hours, %d minutes, %d seconds.\n", 01760 status, credentials, ctimesec / 31536000, 01761 (ctimesec % 31536000) / 86400, (ctimesec % 86400) / 3600, 01762 (ctimesec % 3600) / 60, ctimesec % 60); 01763 } else if (ctimesec > 86400) { 01764 ast_cli(a->fd, "%s%s for %d days, %d hours, %d minutes, %d seconds.\n", 01765 status, credentials, ctimesec / 86400, (ctimesec % 86400) / 3600, 01766 (ctimesec % 3600) / 60, ctimesec % 60); 01767 } else if (ctimesec > 3600) { 01768 ast_cli(a->fd, "%s%s for %d hours, %d minutes, %d seconds.\n", 01769 status, credentials, ctimesec / 3600, (ctimesec % 3600) / 60, 01770 ctimesec % 60); 01771 } else if (ctimesec > 60) { 01772 ast_cli(a->fd, "%s%s for %d minutes, %d seconds.\n", status, credentials, 01773 ctimesec / 60, ctimesec % 60); 01774 } else { 01775 ast_cli(a->fd, "%s%s for %d seconds.\n", status, credentials, ctimesec); 01776 } 01777 01778 return CLI_SUCCESS; 01779 }
| static struct ast_config* realtime_multi_ldap | ( | const char * | basedn, | |
| const char * | table_name, | |||
| va_list | ap | |||
| ) | [static, read] |
See Asterisk doc.
this function will be called for the switch statment if no match is found with the realtime_ldap function(i.e. it is a failover); however, the ast_load_realtime wil match on wildcharacters also depending on what the mode is set to this is an area of asterisk that could do with a lot of modification I think this function returns Realtime dynamic objects
Definition at line 953 of file res_config_ldap.c.
References ast_category_append(), ast_category_new(), ast_config_new(), ast_log(), ast_variable_append(), free, LOG_ERROR, ast_variable::next, ldap_table_config::next, realtime_ldap_base_ap(), and var.
00955 { 00956 struct ast_variable **vars = realtime_ldap_base_ap(NULL, basedn, table_name, ap); 00957 struct ast_config *cfg = NULL; 00958 00959 if (vars) { 00960 cfg = ast_config_new(); 00961 if (!cfg) { 00962 ast_log(LOG_ERROR, "Unable to create a config!\n"); 00963 } else { 00964 struct ast_variable **p = vars; 00965 00966 while (*p) { 00967 struct ast_category *cat = NULL; 00968 cat = ast_category_new("", table_name, -1); 00969 if (!cat) { 00970 ast_log(LOG_ERROR, "Unable to create a new category!\n"); 00971 break; 00972 } else { 00973 struct ast_variable *var = *p; 00974 while (var) { 00975 struct ast_variable *next = var->next; 00976 var->next = NULL; 00977 ast_variable_append(cat, var); 00978 var = next; 00979 } 00980 } 00981 ast_category_append(cfg, cat); 00982 p++; 00983 } 00984 } 00985 free(vars); 00986 } 00987 return cfg; 00988 00989 }
| static int reload | ( | void | ) | [static] |
Definition at line 1563 of file res_config_ldap.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_verb, ldap_lock, ldap_reconnect(), LOG_NOTICE, LOG_WARNING, and parse_config().
01564 { 01565 /* Aquire control before doing anything to the module itself. */ 01566 ast_mutex_lock(&ldap_lock); 01567 01568 if (ldapConn) { 01569 ldap_unbind_ext_s(ldapConn, NULL, NULL); 01570 ldapConn = NULL; 01571 } 01572 01573 if (parse_config() < 0) { 01574 ast_log(LOG_NOTICE, "Cannot reload LDAP RealTime driver.\n"); 01575 ast_mutex_unlock(&ldap_lock); 01576 return 0; 01577 } 01578 01579 if (!ldap_reconnect()) { 01580 ast_log(LOG_WARNING, "Couldn't establish connection to your directory server. Check debug.\n"); 01581 } 01582 01583 ast_verb(2, "LDAP RealTime driver reloaded.\n"); 01584 01585 /* Done reloading. Release lock so others can now use driver. */ 01586 ast_mutex_unlock(&ldap_lock); 01587 01588 return 0; 01589 }
| static int replace_string_in_string | ( | char * | string, | |
| const char * | search, | |||
| const char * | by | |||
| ) | [static] |
Replace <search> by <by> in string.
Definition at line 670 of file res_config_ldap.c.
Referenced by append_var_and_value_to_filter().
00671 { 00672 int search_len = strlen(search); 00673 int by_len = strlen(by); 00674 int replaced = 0; 00675 char *p = strstr(string, search); 00676 00677 if (p) { 00678 replaced = 1; 00679 while (p) { 00680 if (by_len == search_len) { 00681 memcpy(p, by, by_len); 00682 } else { 00683 memmove(p + by_len, p + search_len, strlen(p + search_len) + 1); 00684 memcpy(p, by, by_len); 00685 } 00686 p = strstr(p + by_len, search); 00687 } 00688 } 00689 return replaced; 00690 }
| 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, 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 628 of file res_config_ldap.c.
References ast_calloc, ast_debug, ast_strlen_zero(), MAXRESULT, and pbx_substitute_variables_helper().
Referenced by cleaned_basedn().
00629 { 00630 #define MAXRESULT 2048 00631 char *ret_string = NULL; 00632 00633 if (!ast_strlen_zero(string)) { 00634 ret_string = ast_calloc(1, MAXRESULT); 00635 pbx_substitute_variables_helper(channel, string, ret_string, MAXRESULT - 1); 00636 } 00637 ast_debug(2, "substituted: string: '%s' => '%s' \n", string, ret_string); 00638 return ret_string; 00639 }
| static struct ldap_table_config* table_config_for_table_name | ( | const char * | table_name | ) | [static, read] |
Find a table_config - Should be locked before using it.
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, read] |
Create a new table_config.
Definition at line 105 of file res_config_ldap.c.
References ast_calloc, ast_strdup, free, and ldap_table_config::table_name.
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 1542 of file res_config_ldap.c.
References ARRAY_LEN, ast_cli_unregister_multiple(), ast_config_engine_deregister(), ast_mutex_lock(), ast_mutex_unlock(), ast_verb, ldap_cli, ldap_engine, ldap_lock, and table_configs_free().
01543 { 01544 /* Aquire control before doing anything to the module itself. */ 01545 ast_mutex_lock(&ldap_lock); 01546 01547 table_configs_free(); 01548 01549 if (ldapConn) { 01550 ldap_unbind_ext_s(ldapConn, NULL, NULL); 01551 ldapConn = NULL; 01552 } 01553 ast_cli_unregister_multiple(ldap_cli, ARRAY_LEN(ldap_cli)); 01554 ast_config_engine_deregister(&ldap_engine); 01555 ast_verb(1, "LDAP RealTime driver unloaded.\n"); 01556 01557 /* Unlock so something else can destroy the lock. */ 01558 ast_mutex_unlock(&ldap_lock); 01559 01560 return 0; 01561 }
| static int update2_ldap | ( | const char * | basedn, | |
| const char * | table_name, | |||
| va_list | ap | |||
| ) | [static] |
Definition at line 1325 of file res_config_ldap.c.
References ldap_table_config::additional_filter, append_var_and_value_to_filter(), ast_calloc, ast_debug, ast_free, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_realloc, ast_str_append(), ast_str_buffer(), ast_str_create(), base_table_config, cleaned_basedn(), convert_attribute_name_to_ldap(), filter(), is_ldap_connect_error(), ldap_lock, ldap_reconnect(), LOG_ERROR, LOG_WARNING, option_debug, and table_config_for_table_name().
01326 { 01327 int error = 0; 01328 LDAPMessage *ldap_entry = NULL; 01329 LDAPMod **ldap_mods; 01330 const char *newparam = NULL; 01331 const char *newval = NULL; 01332 char *dn; 01333 int num_entries = 0; 01334 int i = 0; 01335 int mods_size = 0; 01336 int mod_exists = 0; 01337 struct ldap_table_config *table_config = NULL; 01338 char *clean_basedn = NULL; 01339 struct ast_str *filter = NULL; 01340 int tries = 0; 01341 int result = 0; 01342 LDAPMessage *ldap_result_msg = NULL; 01343 01344 if (!table_name) { 01345 ast_log(LOG_ERROR, "No table_name specified.\n"); 01346 return -1; 01347 } 01348 01349 if (!(filter = ast_str_create(80))) { 01350 return -1; 01351 } 01352 01353 ast_mutex_lock(&ldap_lock); 01354 01355 /* We now have our complete statement; Lets connect to the server and execute it. */ 01356 if (!ldap_reconnect()) { 01357 ast_mutex_unlock(&ldap_lock); 01358 ast_free(filter); 01359 return -1; 01360 } 01361 01362 table_config = table_config_for_table_name(table_name); 01363 if (!table_config) { 01364 ast_log(LOG_ERROR, "No table named '%s'.\n", table_name); 01365 ast_mutex_unlock(&ldap_lock); 01366 ast_free(filter); 01367 return -1; 01368 } 01369 01370 clean_basedn = cleaned_basedn(NULL, basedn); 01371 01372 /* Create the filter with the table additional filter and the parameter/value pairs we were given */ 01373 ast_str_append(&filter, 0, "(&"); 01374 if (table_config && table_config->additional_filter) { 01375 ast_str_append(&filter, 0, "%s", table_config->additional_filter); 01376 } 01377 if (table_config != base_table_config && base_table_config 01378 && base_table_config->additional_filter) { 01379 ast_str_append(&filter, 0, "%s", base_table_config->additional_filter); 01380 } 01381 01382 /* Get multiple lookup keyfields and values */ 01383 while ((newparam = va_arg(ap, const char *))) { 01384 newval = va_arg(ap, const char *); 01385 append_var_and_value_to_filter(&filter, table_config, newparam, newval); 01386 } 01387 ast_str_append(&filter, 0, ")"); 01388 01389 /* Create the modification array with the parameter/value pairs we were given, 01390 * if there are several parameters with the same name, we collect them into 01391 * one parameter/value pair and delimit them with a semicolon */ 01392 newparam = va_arg(ap, const char *); 01393 newparam = convert_attribute_name_to_ldap(table_config, newparam); 01394 newval = va_arg(ap, const char *); 01395 if (!newparam || !newval) { 01396 ast_log(LOG_WARNING, "LINE(%d): need at least one parameter to modify.\n", __LINE__); 01397 ast_free(filter); 01398 ast_free(clean_basedn); 01399 return -1; 01400 } 01401 01402 mods_size = 2; /* one for the first param/value pair and one for the the terminating NULL */ 01403 ldap_mods = ast_calloc(sizeof(LDAPMod *), mods_size); 01404 ldap_mods[0] = ast_calloc(1, sizeof(LDAPMod)); 01405 01406 ldap_mods[0]->mod_op = LDAP_MOD_REPLACE; 01407 ldap_mods[0]->mod_type = ast_calloc(sizeof(char), strlen(newparam) + 1); 01408 strcpy(ldap_mods[0]->mod_type, newparam); 01409 01410 ldap_mods[0]->mod_values = ast_calloc(sizeof(char), 2); 01411 ldap_mods[0]->mod_values[0] = ast_calloc(sizeof(char), strlen(newval) + 1); 01412 strcpy(ldap_mods[0]->mod_values[0], newval); 01413 01414 while ((newparam = va_arg(ap, const char *))) { 01415 newparam = convert_attribute_name_to_ldap(table_config, newparam); 01416 newval = va_arg(ap, const char *); 01417 mod_exists = 0; 01418 01419 for (i = 0; i < mods_size - 1; i++) { 01420 if (ldap_mods[i]&& !strcmp(ldap_mods[i]->mod_type, newparam)) { 01421 /* We have the parameter allready, adding the value as a semicolon delimited value */ 01422 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)); 01423 strcat(ldap_mods[i]->mod_values[0], ";"); 01424 strcat(ldap_mods[i]->mod_values[0], newval); 01425 mod_exists = 1; 01426 break; 01427 } 01428 } 01429 01430 /* create new mod */ 01431 if (!mod_exists) { 01432 mods_size++; 01433 ldap_mods = ast_realloc(ldap_mods, sizeof(LDAPMod *) * mods_size); 01434 ldap_mods[mods_size - 1] = NULL; 01435 ldap_mods[mods_size - 2] = ast_calloc(1, sizeof(LDAPMod)); 01436 01437 ldap_mods[mods_size - 2]->mod_op = LDAP_MOD_REPLACE; 01438 01439 ldap_mods[mods_size - 2]->mod_type = ast_calloc(sizeof(char), strlen(newparam) + 1); 01440 strcpy(ldap_mods[mods_size - 2]->mod_type, newparam); 01441 01442 ldap_mods[mods_size - 2]->mod_values = ast_calloc(sizeof(char *), 2); 01443 ldap_mods[mods_size - 2]->mod_values[0] = ast_calloc(sizeof(char), strlen(newval) + 1); 01444 strcpy(ldap_mods[mods_size - 2]->mod_values[0], newval); 01445 } 01446 } 01447 /* freeing ldap_mods further down */ 01448 01449 do { 01450 /* freeing ldap_result further down */ 01451 result = ldap_search_ext_s(ldapConn, clean_basedn, 01452 LDAP_SCOPE_SUBTREE, ast_str_buffer(filter), NULL, 0, NULL, NULL, NULL, LDAP_NO_LIMIT, 01453 &ldap_result_msg); 01454 if (result != LDAP_SUCCESS && is_ldap_connect_error(result)) { 01455 ast_log(LOG_WARNING, "Failed to query database. Try %d/3\n", tries + 1); 01456 tries++; 01457 if (tries < 3) { 01458 usleep(500000L * tries); 01459 if (ldapConn) { 01460 ldap_unbind_ext_s(ldapConn, NULL, NULL); 01461 ldapConn = NULL; 01462 } 01463 if (!ldap_reconnect()) { 01464 break; 01465 } 01466 } 01467 } 01468 } while (result != LDAP_SUCCESS && tries < 3 && is_ldap_connect_error(result)); 01469 01470 if (result != LDAP_SUCCESS) { 01471 ast_log(LOG_WARNING, "Failed to query directory. Error: %s.\n", ldap_err2string(result)); 01472 ast_log(LOG_WARNING, "Query: %s\n", ast_str_buffer(filter)); 01473 01474 ast_mutex_unlock(&ldap_lock); 01475 ast_free(filter); 01476 ast_free(clean_basedn); 01477 ldap_msgfree(ldap_result_msg); 01478 ldap_mods_free(ldap_mods, 0); 01479 return -1; 01480 } 01481 /* Ready to update */ 01482 if ((num_entries = ldap_count_entries(ldapConn, ldap_result_msg)) > 0) { 01483 for (i = 0; option_debug > 2 && i < mods_size - 1; i++) { 01484 ast_debug(3, "LINE(%d) %s=%s \n", __LINE__, ldap_mods[i]->mod_type, ldap_mods[i]->mod_values[0]); 01485 } 01486 01487 ldap_entry = ldap_first_entry(ldapConn, ldap_result_msg); 01488 01489 for (i = 0; ldap_entry; i++) { 01490 dn = ldap_get_dn(ldapConn, ldap_entry); 01491 if ((error = ldap_modify_ext_s(ldapConn, dn, ldap_mods, NULL, NULL)) != LDAP_SUCCESS) { 01492 ast_log(LOG_ERROR, "Couldn't modify dn:%s because %s", dn, ldap_err2string(error)); 01493 } 01494 01495 ldap_entry = ldap_next_entry(ldapConn, ldap_entry); 01496 } 01497 } 01498 01499 ast_mutex_unlock(&ldap_lock); 01500 if (filter) { 01501 ast_free(filter); 01502 } 01503 if (clean_basedn) { 01504 ast_free(clean_basedn); 01505 } 01506 ldap_msgfree(ldap_result_msg); 01507 ldap_mods_free(ldap_mods, 0); 01508 return num_entries; 01509 }
| static int update_ldap | ( | const char * | basedn, | |
| const char * | table_name, | |||
| const char * | attribute, | |||
| const char * | lookup, | |||
| va_list | ap | |||
| ) | [static] |
Definition at line 1140 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(), free, is_ldap_connect_error(), ldap_lock, ldap_reconnect(), LOG_ERROR, LOG_WARNING, option_debug, and table_config_for_table_name().
01142 { 01143 int error = 0; 01144 LDAPMessage *ldap_entry = NULL; 01145 LDAPMod **ldap_mods; 01146 const char *newparam = NULL; 01147 const char *newval = NULL; 01148 char *dn; 01149 int num_entries = 0; 01150 int i = 0; 01151 int mods_size = 0; 01152 int mod_exists = 0; 01153 struct ldap_table_config *table_config = NULL; 01154 char *clean_basedn = NULL; 01155 struct ast_str *filter = NULL; 01156 int tries = 0; 01157 int result = 0; 01158 LDAPMessage *ldap_result_msg = NULL; 01159 01160 if (!table_name) { 01161 ast_log(LOG_ERROR, "No table_name specified.\n"); 01162 return -1; 01163 } 01164 01165 if (!(filter = ast_str_create(80))) { 01166 return -1; 01167 } 01168 01169 if (!attribute || !lookup) { 01170 ast_log(LOG_WARNING, "LINE(%d): search parameters are empty.\n", __LINE__); 01171 return -1; 01172 } 01173 ast_mutex_lock(&ldap_lock); 01174 01175 /* We now have our complete statement; Lets connect to the server and execute it. */ 01176 if (!ldap_reconnect()) { 01177 ast_mutex_unlock(&ldap_lock); 01178 return -1; 01179 } 01180 01181 table_config = table_config_for_table_name(table_name); 01182 if (!table_config) { 01183 ast_log(LOG_ERROR, "No table named '%s'.\n", table_name); 01184 ast_mutex_unlock(&ldap_lock); 01185 return -1; 01186 } 01187 01188 clean_basedn = cleaned_basedn(NULL, basedn); 01189 01190 /* Create the filter with the table additional filter and the parameter/value pairs we were given */ 01191 ast_str_append(&filter, 0, "(&"); 01192 if (table_config && table_config->additional_filter) { 01193 ast_str_append(&filter, 0, "%s", table_config->additional_filter); 01194 } 01195 if (table_config != base_table_config && base_table_config && base_table_config->additional_filter) { 01196 ast_str_append(&filter, 0, "%s", base_table_config->additional_filter); 01197 } 01198 append_var_and_value_to_filter(&filter, table_config, attribute, lookup); 01199 ast_str_append(&filter, 0, ")"); 01200 01201 /* Create the modification array with the parameter/value pairs we were given, 01202 * if there are several parameters with the same name, we collect them into 01203 * one parameter/value pair and delimit them with a semicolon */ 01204 newparam = va_arg(ap, const char *); 01205 newparam = convert_attribute_name_to_ldap(table_config, newparam); 01206 newval = va_arg(ap, const char *); 01207 if (!newparam || !newval) { 01208 ast_log(LOG_WARNING, "LINE(%d): need at least one parameter to modify.\n", __LINE__); 01209 return -1; 01210 } 01211 01212 mods_size = 2; /* one for the first param/value pair and one for the the terminating NULL */ 01213 ldap_mods = ast_calloc(sizeof(LDAPMod *), mods_size); 01214 ldap_mods[0] = ast_calloc(1, sizeof(LDAPMod)); 01215 01216 ldap_mods[0]->mod_op = LDAP_MOD_REPLACE; 01217 ldap_mods[0]->mod_type = ast_calloc(sizeof(char), strlen(newparam) + 1); 01218 strcpy(ldap_mods[0]->mod_type, newparam); 01219 01220 ldap_mods[0]->mod_values = ast_calloc(sizeof(char), 2); 01221 ldap_mods[0]->mod_values[0] = ast_calloc(sizeof(char), strlen(newval) + 1); 01222 strcpy(ldap_mods[0]->mod_values[0], newval); 01223 01224 while ((newparam = va_arg(ap, const char *))) { 01225 newparam = convert_attribute_name_to_ldap(table_config, newparam); 01226 newval = va_arg(ap, const char *); 01227 mod_exists = 0; 01228 01229 for (i = 0; i < mods_size - 1; i++) { 01230 if (ldap_mods[i]&& !strcmp(ldap_mods[i]->mod_type, newparam)) { 01231 /* We have the parameter allready, adding the value as a semicolon delimited value */ 01232 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)); 01233 strcat(ldap_mods[i]->mod_values[0], ";"); 01234 strcat(ldap_mods[i]->mod_values[0], newval); 01235 mod_exists = 1; 01236 break; 01237 } 01238 } 01239 01240 /* create new mod */ 01241 if (!mod_exists) { 01242 mods_size++; 01243 ldap_mods = ast_realloc(ldap_mods, sizeof(LDAPMod *) * mods_size); 01244 ldap_mods[mods_size - 1] = NULL; 01245 01246 ldap_mods[mods_size - 2] = ast_calloc(1, sizeof(LDAPMod)); 01247 01248 ldap_mods[mods_size - 2]->mod_type = ast_calloc(sizeof(char), strlen(newparam) + 1); 01249 strcpy(ldap_mods[mods_size - 2]->mod_type, newparam); 01250 01251 if (strlen(newval) == 0) { 01252 ldap_mods[mods_size - 2]->mod_op = LDAP_MOD_DELETE; 01253 } else { 01254 ldap_mods[mods_size - 2]->mod_op = LDAP_MOD_REPLACE; 01255 01256 ldap_mods[mods_size - 2]->mod_values = ast_calloc(sizeof(char *), 2); 01257 ldap_mods[mods_size - 2]->mod_values[0] = ast_calloc(sizeof(char), strlen(newval) + 1); 01258 strcpy(ldap_mods[mods_size - 2]->mod_values[0], newval); 01259 } 01260 } 01261 } 01262 /* freeing ldap_mods further down */ 01263 01264 do { 01265 /* freeing ldap_result further down */ 01266 result = ldap_search_ext_s(ldapConn, clean_basedn, 01267 LDAP_SCOPE_SUBTREE, ast_str_buffer(filter), NULL, 0, NULL, NULL, NULL, LDAP_NO_LIMIT, 01268 &ldap_result_msg); 01269 if (result != LDAP_SUCCESS && is_ldap_connect_error(result)) { 01270 ast_log(LOG_WARNING, "Failed to query database. Try %d/3\n", tries + 1); 01271 tries++; 01272 if (tries < 3) { 01273 usleep(500000L * tries); 01274 if (ldapConn) { 01275 ldap_unbind_ext_s(ldapConn, NULL, NULL); 01276 ldapConn = NULL; 01277 } 01278 if (!ldap_reconnect()) 01279 break; 01280 } 01281 } 01282 } while (result != LDAP_SUCCESS && tries < 3 && is_ldap_connect_error(result)); 01283 01284 if (result != LDAP_SUCCESS) { 01285 ast_log(LOG_WARNING, "Failed to query directory. Error: %s.\n", ldap_err2string(result)); 01286 ast_log(LOG_WARNING, "Query: %s\n", ast_str_buffer(filter)); 01287 01288 ast_mutex_unlock(&ldap_lock); 01289 free(filter); 01290 free(clean_basedn); 01291 ldap_msgfree(ldap_result_msg); 01292 ldap_mods_free(ldap_mods, 0); 01293 return -1; 01294 } 01295 /* Ready to update */ 01296 if ((num_entries = ldap_count_entries(ldapConn, ldap_result_msg)) > 0) { 01297 ast_debug(3, "LINE(%d) Modifying %s=%s hits: %d\n", __LINE__, attribute, lookup, num_entries); 01298 for (i = 0; option_debug > 2 && i < mods_size - 1; i++) { 01299 if (ldap_mods[i]->mod_op != LDAP_MOD_DELETE) { 01300 ast_debug(3, "LINE(%d) %s=%s \n", __LINE__, ldap_mods[i]->mod_type, ldap_mods[i]->mod_values[0]); 01301 } else { 01302 ast_debug(3, "LINE(%d) deleting %s \n", __LINE__, ldap_mods[i]->mod_type); 01303 } 01304 } 01305 ldap_entry = ldap_first_entry(ldapConn, ldap_result_msg); 01306 01307 for (i = 0; ldap_entry; i++) { 01308 dn = ldap_get_dn(ldapConn, ldap_entry); 01309 if ((error = ldap_modify_ext_s(ldapConn, dn, ldap_mods, NULL, NULL)) != LDAP_SUCCESS) { 01310 ast_log(LOG_ERROR, "Couldn't modify dn:%s because %s", dn, ldap_err2string(error)); 01311 } 01312 01313 ldap_entry = ldap_next_entry(ldapConn, ldap_entry); 01314 } 01315 } 01316 01317 ast_mutex_unlock(&ldap_lock); 01318 ast_free(filter); 01319 ast_free(clean_basedn); 01320 ldap_msgfree(ldap_result_msg); 01321 ldap_mods_free(ldap_mods, 0); 01322 return num_entries; 01323 }
| static struct ast_variable* variable_named | ( | struct ast_variable * | var, | |
| const char * | name | |||
| ) | [static, read] |
Find variable by name.
Definition at line 137 of file res_config_ldap.c.
References ast_variable::name, and ast_variable::next.
Referenced by config_ldap(), realtime_ldap_result_to_vars(), and semicolon_count_var().
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_DEFAULT , .description = "LDAP realtime interface" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, .reload = reload, } [static] |
Definition at line 1785 of file res_config_ldap.c.
struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 1785 of file res_config_ldap.c.
char base_distinguished_name[512] [static] |
Definition at line 69 of file res_config_ldap.c.
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(), and pgsql_reconnect().
struct ast_cli_entry ldap_cli[] [static] |
Initial value:
{
AST_CLI_DEFINE(realtime_ldap_status, "Shows connection information for the LDAP RealTime driver"),
}
Definition at line 100 of file res_config_ldap.c.
Referenced by load_module(), and unload_module().
struct ast_config_engine ldap_engine [static] |
Definition at line 1511 of file res_config_ldap.c.
Referenced by load_module(), and unload_module().
ast_mutex_t ldap_lock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER ) [static] |
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.
char pass[50] [static] |
Definition at line 68 of file res_config_ldap.c.
Referenced by __ast_dsp_call_progress(), __get_header(), add_mod(), ast_db_deltree(), ast_db_gettree(), build_transactions(), gtalk_create_candidates(), handle_cli_database_show(), handle_cli_database_showkey(), jingle_create_candidates(), and login_exec().
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(), exchangecal_load_calendar(), ical_load_calendar(), queue_exec(), reqprep(), respprep(), sendurl_exec(), and sip_sendhtml().
char user[512] [static] |
Definition at line 67 of file res_config_ldap.c.
int version = 3 [static] |
Definition at line 70 of file res_config_ldap.c.
1.5.6