ldap plugin for portable configuration engine (ARA) More...
#include "asterisk.h"#include <stdlib.h>#include <string.h>#include <ctype.h>#include <stdio.h>#include <ldap.h>#include "asterisk/channel.h"#include "asterisk/logger.h"#include "asterisk/config.h"#include "asterisk/module.h"#include "asterisk/lock.h"#include "asterisk/options.h"#include "asterisk/cli.h"#include "asterisk/utils.h"#include "asterisk/strings.h"#include "asterisk/pbx.h"#include "asterisk/linkedlists.h"
Go to the source code of this file.
Data Structures | |
| struct | category_and_metric |
| struct | ldap_table_config |
| Table configuration. More... | |
| struct | table_configs |
| Should be locked before using it. More... | |
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) |
| caller should free returned pointer | |
| 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 - Should be locked before using it. | |
| 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) |
| 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) |
| 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 - Should be locked before using it. | |
| 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. No check is done on string allocated size ! | |
| 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) |
| caller should free returned pointer | |
| 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_GLOBAL_SYMBOLS , .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 = "0901e4e500243c855563a2d78b0c03e4" , .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_RECURSIVE_MUTEX_INITIALIZER_NP ) |
| 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 |
ldap plugin for portable configuration engine (ARA)
Definition in file res_config_ldap.c.
| #define MAXRESULT 2048 |
| #define RES_CONFIG_LDAP_CONF "res_ldap.conf" |
Definition at line 60 of file res_config_ldap.c.
Referenced by config_ldap(), and parse_config().
| #define RES_CONFIG_LDAP_DEFAULT_BASEDN "asterisk" |
Definition at line 61 of file res_config_ldap.c.
Referenced by parse_config().
| static void __reg_module | ( | void | ) | [static] |
Definition at line 1768 of file res_config_ldap.c.
| static void __unreg_module | ( | void | ) | [static] |
Definition at line 1768 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 685 of file res_config_ldap.c.
References ast_debug, ast_str_append(), convert_attribute_name_to_ldap(), len(), and replace_string_in_string().
Referenced by realtime_ldap_base_ap(), update2_ldap(), and update_ldap().
00688 { 00689 char *new_name = NULL; 00690 char *new_value = NULL; 00691 char *like_pos = strstr(name, " LIKE"); 00692 00693 ast_debug(2, "name='%s' value='%s'\n", name, value); 00694 00695 if (like_pos) { 00696 int len = like_pos - name; 00697 name = new_name = ast_strdupa(name); 00698 new_name[len] = '\0'; 00699 value = new_value = ast_strdupa(value); 00700 replace_string_in_string(new_value, "\\_", "_"); 00701 replace_string_in_string(new_value, "%", "*"); 00702 } 00703 00704 name = convert_attribute_name_to_ldap(table_config, name); 00705 00706 ast_str_append(filter, 0, "(%s=%s)", name, value); 00707 }
| static char* cleaned_basedn | ( | struct ast_channel * | channel, | |
| const char * | basedn | |||
| ) | [static] |
caller should free returned pointer
Definition at line 635 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().
00636 { 00637 char *cbasedn = NULL; 00638 if (basedn) { 00639 char *p = NULL; 00640 cbasedn = substituted(channel, basedn); 00641 if (*cbasedn == '"') { 00642 cbasedn++; 00643 if (!ast_strlen_zero(cbasedn)) { 00644 int len = strlen(cbasedn); 00645 if (cbasedn[len - 1] == '"') 00646 cbasedn[len - 1] = '\0'; 00647 00648 } 00649 } 00650 p = cbasedn; 00651 while (*p) { 00652 if (*p == '|') 00653 *p = ','; 00654 p++; 00655 } 00656 } 00657 ast_debug(2, "basedn: '%s' => '%s' \n", basedn, cbasedn); 00658 return cbasedn; 00659 }
| 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 986 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().
00987 { 00988 const struct category_and_metric *as = a; 00989 const struct category_and_metric *bs = b; 00990 00991 if (as->metric < bs->metric) 00992 return -1; 00993 else if (as->metric > bs->metric) 00994 return 1; 00995 else if (as->metric == bs->metric && strcmp(as->name, bs->name) != 0) 00996 return strcmp(as->name, bs->name); 00997 00998 /* if the metric and the category name is the same, we check the variable metric */ 00999 if (as->var_metric < bs->var_metric) 01000 return -1; 01001 else if (as->var_metric > bs->var_metric) 01002 return 1; 01003 01004 return 0; 01005 }
| 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 1014 of file res_config_ldap.c.
References ast_calloc, ast_category_append(), ast_category_new(), ast_config_internal_load(), ast_debug, ast_log(), ast_strlen_zero(), ast_variable_append(), ast_variable_new(), compare_categories(), free, 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.
01016 { 01017 unsigned int vars_count = 0; 01018 struct ast_variable **vars; 01019 int i = 0; 01020 struct ast_variable *new_v = NULL; 01021 struct ast_category *cur_cat = NULL; 01022 const char *last_category = NULL; 01023 int last_category_metric = 0; 01024 struct category_and_metric *categories; 01025 struct ast_variable **p; 01026 01027 if (ast_strlen_zero(file) || !strcasecmp(file, RES_CONFIG_LDAP_CONF)) { 01028 ast_log(LOG_ERROR, "Cannot configure myself.\n"); 01029 return NULL; 01030 } 01031 01032 vars = realtime_ldap_base(&vars_count, basedn, table_name, "filename", 01033 file, "commented", "FALSE", NULL); 01034 01035 if (!vars) { 01036 ast_log(LOG_WARNING, "Could not find config '%s' in database.\n", file); 01037 return NULL; 01038 } 01039 01040 /*!\note Since the items come back in random order, they need to be sorted 01041 * first, and since the data could easily exceed stack size, this is 01042 * allocated from the heap. 01043 */ 01044 if (!(categories = ast_calloc(sizeof(*categories), vars_count))) 01045 return NULL; 01046 01047 for (vars_count = 0, p = vars; *p; p++) { 01048 struct ast_variable *category = variable_named(*p, "category"); 01049 struct ast_variable *cat_metric = variable_named(*p, "cat_metric"); 01050 struct ast_variable *var_name = variable_named(*p, "variable_name"); 01051 struct ast_variable *var_val = variable_named(*p, "variable_value"); 01052 struct ast_variable *var_metric = variable_named(*p, "var_metric"); 01053 struct ast_variable *dn = variable_named(*p, "dn"); 01054 01055 ast_debug(1, "category: %s\n", category->value); 01056 ast_debug(1, "var_name: %s\n", var_name->value); 01057 ast_debug(1, "var_val: %s\n", var_val->value); 01058 ast_debug(1, "cat_metric: %s\n", cat_metric->value); 01059 01060 if (!category) { 01061 ast_log(LOG_ERROR, 01062 "No category name in entry '%s' for file '%s'.\n", 01063 (dn ? dn->value : "?"), file); 01064 } else if (!cat_metric) { 01065 ast_log(LOG_ERROR, 01066 "No category metric in entry '%s'(category: %s) for file '%s'.\n", 01067 (dn ? dn->value : "?"), category->value, file); 01068 } else if (!var_metric) { 01069 ast_log(LOG_ERROR, 01070 "No variable metric in entry '%s'(category: %s) for file '%s'.\n", 01071 (dn ? dn->value : "?"), category->value, file); 01072 } else if (!var_name) { 01073 ast_log(LOG_ERROR, 01074 "No variable name in entry '%s' (category: %s metric: %s) for file '%s'.\n", 01075 (dn ? dn->value : "?"), category->value, 01076 cat_metric->value, file); 01077 } else if (!var_val) { 01078 ast_log(LOG_ERROR, 01079 "No variable value in entry '%s' (category: %s metric: %s variable: %s) for file '%s'.\n", 01080 (dn ? dn->value : "?"), category->value, 01081 cat_metric->value, var_name->value, file); 01082 } else { 01083 categories[vars_count].name = category->value; 01084 categories[vars_count].metric = atoi(cat_metric->value); 01085 categories[vars_count].variable_name = var_name->value; 01086 categories[vars_count].variable_value = var_val->value; 01087 categories[vars_count].var_metric = atoi(var_metric->value); 01088 vars_count++; 01089 } 01090 } 01091 01092 qsort(categories, vars_count, sizeof(*categories), compare_categories); 01093 01094 for (i = 0; i < vars_count; i++) { 01095 if (!strcmp(categories[i].variable_name, "#include")) { 01096 struct ast_flags flags = { 0 }; 01097 if (!ast_config_internal_load(categories[i].variable_value, cfg, flags, "", who_asked)) 01098 break; 01099 continue; 01100 } 01101 01102 if (!last_category || strcmp(last_category, categories[i].name) || 01103 last_category_metric != categories[i].metric) { 01104 cur_cat = ast_category_new(categories[i].name, table_name, -1); 01105 if (!cur_cat) 01106 break; 01107 last_category = categories[i].name; 01108 last_category_metric = categories[i].metric; 01109 ast_category_append(cfg, cur_cat); 01110 } 01111 01112 if (!(new_v = ast_variable_new(categories[i].variable_name, categories[i].variable_value, table_name))) 01113 break; 01114 01115 ast_variable_append(cur_cat, new_v); 01116 } 01117 01118 free(vars); 01119 free(categories); 01120 01121 return cfg; 01122 }
| 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 - Should be locked before using it.
Definition at line 240 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().
00242 { 00243 int i = 0; 00244 struct ldap_table_config *configs[] = { table_config, base_table_config }; 00245 00246 for (i = 0; i < ARRAY_LEN(configs); i++) { 00247 struct ast_variable *attribute; 00248 00249 if (!configs[i]) 00250 continue; 00251 00252 attribute = configs[i]->attributes; 00253 for (; attribute; attribute = attribute->next) { 00254 if (strcasecmp(attribute_name, attribute->value) == 0) 00255 return attribute->name; 00256 } 00257 } 00258 00259 return attribute_name; 00260 }
| 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 217 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().
00219 { 00220 int i = 0; 00221 struct ldap_table_config *configs[] = { table_config, base_table_config }; 00222 00223 for (i = 0; i < ARRAY_LEN(configs); i++) { 00224 struct ast_variable *attribute; 00225 00226 if (!configs[i]) 00227 continue; 00228 00229 attribute = configs[i]->attributes; 00230 for (; attribute; attribute = attribute->next) { 00231 if (!strcasecmp(attribute_name, attribute->name)) 00232 return attribute->value; 00233 } 00234 } 00235 00236 return attribute_name; 00237 }
| static int is_ldap_connect_error | ( | int | err | ) | [static] |
Definition at line 534 of file res_config_ldap.c.
Referenced by ldap_loadentry(), realtime_ldap_base_ap(), update2_ldap(), and update_ldap().
| 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 543 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().
00545 { 00546 if (!table_config) { 00547 ast_log(LOG_ERROR, "No table config\n"); 00548 return NULL; 00549 } else { 00550 struct ast_variable **vars = NULL; 00551 struct ast_variable *var = NULL; 00552 int result = -1; 00553 LDAPMessage *ldap_result_msg = NULL; 00554 int tries = 0; 00555 00556 ast_debug(2, "ldap_loadentry dn=%s\n", dn); 00557 00558 do { 00559 result = ldap_search_ext_s(ldapConn, dn, LDAP_SCOPE_BASE, 00560 "(objectclass=*)", NULL, 0, NULL, NULL, NULL, LDAP_NO_LIMIT, &ldap_result_msg); 00561 if (result != LDAP_SUCCESS && is_ldap_connect_error(result)) { 00562 ast_log(LOG_WARNING, 00563 "Failed to query database. Try %d/3\n", 00564 tries + 1); 00565 tries++; 00566 if (tries < 3) { 00567 usleep(500000L * tries); 00568 if (ldapConn) { 00569 ldap_unbind_ext_s(ldapConn, NULL, NULL); 00570 ldapConn = NULL; 00571 } 00572 if (!ldap_reconnect()) 00573 break; 00574 } 00575 } 00576 } while (result != LDAP_SUCCESS && tries < 3 && is_ldap_connect_error(result)); 00577 00578 if (result != LDAP_SUCCESS) { 00579 ast_log(LOG_WARNING, 00580 "Failed to query database. Check debug for more info.\n"); 00581 ast_debug(2, "dn=%s\n", dn); 00582 ast_debug(2, "Query Failed because: %s\n", 00583 ldap_err2string(result)); 00584 ast_mutex_unlock(&ldap_lock); 00585 return NULL; 00586 } else { 00587 int num_entry = 0; 00588 unsigned int *entries_count_ptr = NULL; /*!< not using this */ 00589 if ((num_entry = ldap_count_entries(ldapConn, ldap_result_msg)) > 0) { 00590 ast_debug(3, "num_entry: %d\n", num_entry); 00591 00592 vars = realtime_ldap_result_to_vars(table_config, ldap_result_msg, entries_count_ptr); 00593 if (num_entry > 1) 00594 ast_log(LOG_NOTICE, "More than one entry for dn=%s. Take only 1st one\n", dn); 00595 } else { 00596 ast_debug(2, "Could not find any entry dn=%s.\n", dn); 00597 } 00598 } 00599 ldap_msgfree(ldap_result_msg); 00600 00601 /* Chopping \a vars down to one variable */ 00602 if (vars != NULL) { 00603 struct ast_variable **p = vars; 00604 p++; 00605 var = *p; 00606 while (var) { 00607 ast_variables_destroy(var); 00608 p++; 00609 } 00610 vars = ast_realloc(vars, sizeof(struct ast_variable *)); 00611 } 00612 00613 var = *vars; 00614 00615 return var; 00616 } 00617 }
| static int ldap_reconnect | ( | void | ) | [static] |
Definition at line 1669 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().
01670 { 01671 int bind_result = 0; 01672 struct berval cred; 01673 01674 if (ldapConn) { 01675 ast_debug(2, "Everything seems fine.\n"); 01676 return 1; 01677 } 01678 01679 if (ast_strlen_zero(url)) { 01680 ast_log(LOG_ERROR, "Not enough parameters to connect to ldap database\n"); 01681 return 0; 01682 } 01683 01684 if (LDAP_SUCCESS != ldap_initialize(&ldapConn, url)) { 01685 ast_log(LOG_ERROR, "Failed to init ldap connection to '%s'. Check debug for more info.\n", url); 01686 return 0; 01687 } 01688 01689 if (LDAP_OPT_SUCCESS != ldap_set_option(ldapConn, LDAP_OPT_PROTOCOL_VERSION, &version)) { 01690 ast_log(LOG_WARNING, "Unable to set LDAP protocol version to %d, falling back to default.\n", version); 01691 } 01692 01693 if (!ast_strlen_zero(user)) { 01694 ast_debug(2, "bind to '%s' as user '%s'\n", url, user); 01695 cred.bv_val = (char *) pass; 01696 cred.bv_len = strlen(pass); 01697 bind_result = ldap_sasl_bind_s(ldapConn, user, LDAP_SASL_SIMPLE, &cred, NULL, NULL, NULL); 01698 } else { 01699 ast_debug(2, "bind %s anonymously\n", url); 01700 cred.bv_val = NULL; 01701 cred.bv_len = 0; 01702 bind_result = ldap_sasl_bind_s(ldapConn, NULL, LDAP_SASL_SIMPLE, &cred, NULL, NULL, NULL); 01703 } 01704 if (bind_result == LDAP_SUCCESS) { 01705 ast_debug(2, "Successfully connected to database.\n"); 01706 connect_time = time(NULL); 01707 return 1; 01708 } else { 01709 ast_log(LOG_WARNING, "bind failed: %s\n", ldap_err2string(bind_result)); 01710 ldap_unbind_ext_s(ldapConn, NULL, NULL); 01711 ldapConn = NULL; 01712 return 0; 01713 } 01714 }
| 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 180 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().
00182 { 00183 struct ast_variable *var; 00184 00185 if (ast_strlen_zero(attribute_name) || ast_strlen_zero(attribute_value)) 00186 return; 00187 00188 if (!(var = ast_variable_new(attribute_name, attribute_value, table_config->table_name))) 00189 return; 00190 00191 if (table_config->attributes) 00192 var->next = table_config->attributes; 00193 table_config->attributes = var; 00194 }
| static int load_module | ( | void | ) | [static] |
Definition at line 1507 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_NOTICE, LOG_WARNING, and parse_config().
01508 { 01509 if (parse_config() < 0) { 01510 ast_log(LOG_NOTICE, "Cannot load LDAP RealTime driver.\n"); 01511 return 0; 01512 } 01513 01514 ast_mutex_lock(&ldap_lock); 01515 01516 if (!ldap_reconnect()) 01517 ast_log(LOG_WARNING, "Couldn't establish connection. Check debug.\n"); 01518 01519 ast_config_engine_register(&ldap_engine); 01520 ast_verb(1, "LDAP RealTime driver loaded.\n"); 01521 ast_cli_register_multiple(ldap_cli, ARRAY_LEN(ldap_cli)); 01522 01523 ast_mutex_unlock(&ldap_lock); 01524 01525 return 0; 01526 }
| int parse_config | ( | void | ) | [static] |
< using the [config] context for Static RealTime
Definition at line 1576 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.
Referenced by load_module(), and reload().
01577 { 01578 struct ast_config *config; 01579 struct ast_flags config_flags = {0}; 01580 const char *s, *host; 01581 int port; 01582 char *category_name = NULL; 01583 01584 config = ast_config_load(RES_CONFIG_LDAP_CONF, config_flags); 01585 if (config == CONFIG_STATUS_FILEMISSING || config == CONFIG_STATUS_FILEINVALID) { 01586 ast_log(LOG_WARNING, "Cannot load configuration %s\n", RES_CONFIG_LDAP_CONF); 01587 return -1; 01588 } 01589 01590 if (!(s = ast_variable_retrieve(config, "_general", "user"))) { 01591 ast_log(LOG_WARNING, "No directory user found, anonymous binding as default.\n"); 01592 user[0] = '\0'; 01593 } else 01594 ast_copy_string(user, s, sizeof(user)); 01595 01596 if (!ast_strlen_zero(user)) { 01597 if (!(s = ast_variable_retrieve(config, "_general", "pass"))) { 01598 ast_log(LOG_WARNING, "No directory password found, using 'asterisk' as default.\n"); 01599 ast_copy_string(pass, "asterisk", sizeof(pass)); 01600 } else { 01601 ast_copy_string(pass, s, sizeof(pass)); 01602 } 01603 } 01604 01605 /* URL is preferred, use host and port if not found */ 01606 if ((s = ast_variable_retrieve(config, "_general", "url"))) { 01607 ast_copy_string(url, s, sizeof(url)); 01608 } else if ((host = ast_variable_retrieve(config, "_general", "host"))) { 01609 if (!(s = ast_variable_retrieve(config, "_general", "port")) || sscanf(s, "%5d", &port) != 1 || port > 65535) { 01610 ast_log(LOG_NOTICE, "No directory port found, using 389 as default.\n"); 01611 port = 389; 01612 } 01613 01614 snprintf(url, sizeof(url), "ldap://%s:%d", host, port); 01615 } else { 01616 ast_log(LOG_ERROR, "No directory URL or host found.\n"); 01617 ast_config_destroy(config); 01618 return -1; 01619 } 01620 01621 if (!(s = ast_variable_retrieve(config, "_general", "basedn"))) { 01622 ast_log(LOG_ERROR, "No LDAP base dn found, using '%s' as default.\n", RES_CONFIG_LDAP_DEFAULT_BASEDN); 01623 ast_copy_string(base_distinguished_name, RES_CONFIG_LDAP_DEFAULT_BASEDN, sizeof(base_distinguished_name)); 01624 } else 01625 ast_copy_string(base_distinguished_name, s, sizeof(base_distinguished_name)); 01626 01627 if (!(s = ast_variable_retrieve(config, "_general", "version")) && !(s = ast_variable_retrieve(config, "_general", "protocol"))) { 01628 ast_log(LOG_NOTICE, "No explicit LDAP version found, using 3 as default.\n"); 01629 version = 3; 01630 } else if (sscanf(s, "%30d", &version) != 1 || version < 1 || version > 6) { 01631 ast_log(LOG_WARNING, "Invalid LDAP version '%s', using 3 as default.\n", s); 01632 version = 3; 01633 } 01634 01635 table_configs_free(); 01636 01637 while ((category_name = ast_category_browse(config, category_name))) { 01638 int is_general = (strcasecmp(category_name, "_general") == 0); 01639 int is_config = (strcasecmp(category_name, "config") == 0); /*!< using the [config] context for Static RealTime */ 01640 struct ast_variable *var = ast_variable_browse(config, category_name); 01641 01642 if (var) { 01643 struct ldap_table_config *table_config = 01644 table_config_for_table_name(category_name); 01645 if (!table_config) { 01646 table_config = table_config_new(category_name); 01647 AST_LIST_INSERT_HEAD(&table_configs, table_config, entry); 01648 if (is_general) 01649 base_table_config = table_config; 01650 if (is_config) 01651 static_table_config = table_config; 01652 } 01653 for (; var; var = var->next) { 01654 if (!strcasecmp(var->name, "additionalFilter")) { 01655 table_config->additional_filter = ast_strdup(var->value); 01656 } else { 01657 ldap_table_config_add_attribute(table_config, var->name, var->value); 01658 } 01659 } 01660 } 01661 } 01662 01663 ast_config_destroy(config); 01664 01665 return 1; 01666 }
| 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 906 of file res_config_ldap.c.
References free, ast_variable::next, realtime_ldap_base_ap(), and var.
00908 { 00909 struct ast_variable **vars = realtime_ldap_base_ap(NULL, basedn, table_name, ap); 00910 struct ast_variable *var = NULL; 00911 00912 if (vars) { 00913 struct ast_variable *last_var = NULL; 00914 struct ast_variable **p = vars; 00915 while (*p) { 00916 if (last_var) { 00917 while (last_var->next) 00918 last_var = last_var->next; 00919 last_var->next = *p; 00920 } else { 00921 var = *p; 00922 last_var = var; 00923 } 00924 p++; 00925 } 00926 free(vars); 00927 } 00928 return var; 00929 }
| 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 889 of file res_config_ldap.c.
References realtime_ldap_base_ap().
Referenced by config_ldap().
00891 { 00892 struct ast_variable **vars = NULL; 00893 va_list ap; 00894 00895 va_start(ap, table_name); 00896 vars = realtime_ldap_base_ap(entries_count_ptr, basedn, table_name, ap); 00897 va_end(ap); 00898 00899 return vars; 00900 }
| 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 717 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_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().
00719 { 00720 struct ast_variable **vars = NULL; 00721 const char *newparam = NULL; 00722 const char *newval = NULL; 00723 struct ldap_table_config *table_config = NULL; 00724 char *clean_basedn = cleaned_basedn(NULL, basedn); 00725 struct ast_str *filter = NULL; 00726 int tries = 0; 00727 int result = 0; 00728 LDAPMessage *ldap_result_msg = NULL; 00729 00730 if (!table_name) { 00731 ast_log(LOG_WARNING, "No table_name specified.\n"); 00732 ast_free(clean_basedn); 00733 return NULL; 00734 } 00735 00736 if (!(filter = ast_str_create(80))) { 00737 ast_free(clean_basedn); 00738 return NULL; 00739 } 00740 00741 /* Get the first parameter and first value in our list of passed paramater/value pairs */ 00742 newparam = va_arg(ap, const char *); 00743 newval = va_arg(ap, const char *); 00744 00745 if (!newparam || !newval) { 00746 ast_log(LOG_WARNING, "Realtime retrieval requires at least 1 parameter" 00747 " and 1 value to search on.\n"); 00748 ast_free(filter); 00749 ast_free(clean_basedn); 00750 return NULL; 00751 } 00752 00753 ast_mutex_lock(&ldap_lock); 00754 00755 /* We now have our complete statement; Lets connect to the server and execute it. */ 00756 if (!ldap_reconnect()) { 00757 ast_mutex_unlock(&ldap_lock); 00758 ast_free(filter); 00759 ast_free(clean_basedn); 00760 return NULL; 00761 } 00762 00763 table_config = table_config_for_table_name(table_name); 00764 if (!table_config) { 00765 ast_log(LOG_WARNING, "No table named '%s'.\n", table_name); 00766 ast_mutex_unlock(&ldap_lock); 00767 ast_free(filter); 00768 ast_free(clean_basedn); 00769 return NULL; 00770 } 00771 00772 ast_str_append(&filter, 0, "(&"); 00773 00774 if (table_config && table_config->additional_filter) 00775 ast_str_append(&filter, 0, "%s", table_config->additional_filter); 00776 if (table_config != base_table_config && base_table_config && 00777 base_table_config->additional_filter) { 00778 ast_str_append(&filter, 0, "%s", base_table_config->additional_filter); 00779 } 00780 00781 /* Create the first part of the query using the first parameter/value pairs we just extracted */ 00782 /* If there is only 1 set, then we have our query. Otherwise, loop thru the list and concat */ 00783 00784 append_var_and_value_to_filter(&filter, table_config, newparam, newval); 00785 while ((newparam = va_arg(ap, const char *))) { 00786 newval = va_arg(ap, const char *); 00787 append_var_and_value_to_filter(&filter, table_config, newparam, newval); 00788 } 00789 ast_str_append(&filter, 0, ")"); 00790 00791 do { 00792 /* freeing ldap_result further down */ 00793 result = ldap_search_ext_s(ldapConn, clean_basedn, 00794 LDAP_SCOPE_SUBTREE, ast_str_buffer(filter), NULL, 0, NULL, NULL, NULL, LDAP_NO_LIMIT, 00795 &ldap_result_msg); 00796 if (result != LDAP_SUCCESS && is_ldap_connect_error(result)) { 00797 ast_log(LOG_DEBUG, "Failed to query database. Try %d/10\n", 00798 tries + 1); 00799 if (++tries < 10) { 00800 usleep(1); 00801 if (ldapConn) { 00802 ldap_unbind_ext_s(ldapConn, NULL, NULL); 00803 ldapConn = NULL; 00804 } 00805 if (!ldap_reconnect()) 00806 break; 00807 } 00808 } 00809 } while (result != LDAP_SUCCESS && tries < 10 && is_ldap_connect_error(result)); 00810 00811 if (result != LDAP_SUCCESS) { 00812 ast_log(LOG_WARNING, "Failed to query database. Check debug for more info.\n"); 00813 ast_log(LOG_WARNING, "Query: %s\n", ast_str_buffer(filter)); 00814 ast_log(LOG_WARNING, "Query Failed because: %s\n", ldap_err2string(result)); 00815 } else { 00816 /* this is where we create the variables from the search result 00817 * freeing this \a vars outside this function */ 00818 if (ldap_count_entries(ldapConn, ldap_result_msg) > 0) { 00819 /* is this a static var or some other? they are handled different for delimited values */ 00820 vars = realtime_ldap_result_to_vars(table_config, ldap_result_msg, entries_count_ptr); 00821 } else { 00822 ast_debug(1, "Could not find any entry matching %s in base dn %s.\n", 00823 ast_str_buffer(filter), clean_basedn); 00824 } 00825 00826 ldap_msgfree(ldap_result_msg); 00827 00828 /* TODO: get the default variables from the accountBaseDN, not implemented with delimited values */ 00829 if (vars) { 00830 struct ast_variable **p = vars; 00831 while (*p) { 00832 struct ast_variable *append_var = NULL; 00833 struct ast_variable *tmp = *p; 00834 while (tmp) { 00835 if (strcasecmp(tmp->name, "accountBaseDN") == 0) { 00836 /* Get the variable to compare with for the defaults */ 00837 struct ast_variable *base_var = ldap_loadentry(table_config, tmp->value); 00838 00839 while (base_var) { 00840 struct ast_variable *next = base_var->next; 00841 struct ast_variable *test_var = *p; 00842 int base_var_found = 0; 00843 00844 /* run throught the default values and fill it inn if it is missing */ 00845 while (test_var) { 00846 if (strcasecmp(test_var->name, base_var->name) == 0) { 00847 base_var_found = 1; 00848 break; 00849 } else 00850 test_var = test_var->next; 00851 } 00852 if (base_var_found) { 00853 base_var->next = NULL; 00854 ast_variables_destroy(base_var); 00855 base_var = next; 00856 } else { 00857 if (append_var) 00858 base_var->next = append_var; 00859 else 00860 base_var->next = NULL; 00861 append_var = base_var; 00862 base_var = next; 00863 } 00864 } 00865 } 00866 if (!tmp->next && append_var) { 00867 tmp->next = append_var; 00868 tmp = NULL; 00869 } else 00870 tmp = tmp->next; 00871 } 00872 p++; 00873 } 00874 } 00875 } 00876 00877 if (filter) 00878 ast_free(filter); 00879 00880 if (clean_basedn) 00881 ast_free(clean_basedn); 00882 00883 ast_mutex_unlock(&ldap_lock); 00884 00885 return vars; 00886 }
| 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 - Should be locked before using it.
Definition at line 265 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, and var.
Referenced by realtime_ldap_result_to_vars().
00267 { 00268 BerElement *ber = NULL; 00269 struct ast_variable *var = NULL; 00270 struct ast_variable *prev = NULL; 00271 int is_delimited = 0; 00272 int i = 0; 00273 char *ldap_attribute_name; 00274 struct berval *value; 00275 int pos = 0; 00276 00277 ldap_attribute_name = ldap_first_attribute(ldapConn, ldap_entry, &ber); 00278 00279 while (ldap_attribute_name) { 00280 struct berval **values = NULL; 00281 const char *attribute_name = convert_attribute_name_from_ldap(table_config, ldap_attribute_name); 00282 int is_realmed_password_attribute = strcasecmp(attribute_name, "md5secret") == 0; 00283 00284 values = ldap_get_values_len(ldapConn, ldap_entry, ldap_attribute_name); /* these are freed at the end */ 00285 if (values) { 00286 struct berval **v; 00287 char *valptr; 00288 00289 for (v = values; *v; v++) { 00290 value = *v; 00291 valptr = value->bv_val; 00292 ast_debug(2, "LINE(%d) attribute_name: %s LDAP value: %s\n", __LINE__, attribute_name, valptr); 00293 if (is_realmed_password_attribute) { 00294 if (!strncasecmp(valptr, "{md5}", 5)) { 00295 valptr += 5; 00296 } else { 00297 valptr = NULL; 00298 } 00299 ast_debug(2, "md5: %s\n", valptr); 00300 } 00301 if (valptr) { 00302 /* ok, so looping through all delimited values except the last one (not, last character is not delimited...) */ 00303 if (is_delimited) { 00304 i = 0; 00305 pos = 0; 00306 while (!ast_strlen_zero(valptr + i)) { 00307 if (valptr[i] == ';'){ 00308 valptr[i] = '\0'; 00309 if (prev) { 00310 prev->next = ast_variable_new(attribute_name, &valptr[pos], table_config->table_name); 00311 if (prev->next) { 00312 prev = prev->next; 00313 } 00314 } else { 00315 prev = var = ast_variable_new(attribute_name, &valptr[pos], table_config->table_name); 00316 } 00317 pos = i + 1; 00318 } 00319 i++; 00320 } 00321 } 00322 /* for the last delimited value or if the value is not delimited: */ 00323 if (prev) { 00324 prev->next = ast_variable_new(attribute_name, &valptr[pos], table_config->table_name); 00325 if (prev->next) { 00326 prev = prev->next; 00327 } 00328 } else { 00329 prev = var = ast_variable_new(attribute_name, &valptr[pos], table_config->table_name); 00330 } 00331 } 00332 } 00333 ldap_value_free_len(values); 00334 } 00335 ldap_attribute_name = ldap_next_attribute(ldapConn, ldap_entry, ber); 00336 } 00337 ber_free(ber, 0); 00338 00339 return var; 00340 }
| 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 348 of file res_config_ldap.c.
References ast_calloc, ast_debug, ast_strdup, ast_strlen_zero(), ast_variable_new(), ast_variables_destroy(), convert_attribute_name_from_ldap(), free, ast_variable::next, option_debug, realtime_ldap_entry_to_var(), semicolon_count_str(), semicolon_count_var(), static_table_config, ldap_table_config::table_name, ast_variable::value, var, and variable_named().
Referenced by ldap_loadentry(), and realtime_ldap_base_ap().
00350 { 00351 struct ast_variable **vars; 00352 int i = 0; 00353 int tot_count = 0; 00354 int entry_index = 0; 00355 LDAPMessage *ldap_entry = NULL; 00356 BerElement *ber = NULL; 00357 struct ast_variable *var = NULL; 00358 struct ast_variable *prev = NULL; 00359 int is_delimited = 0; 00360 char *delim_value = NULL; 00361 int delim_tot_count = 0; 00362 int delim_count = 0; 00363 00364 /* First find the total count */ 00365 ldap_entry = ldap_first_entry(ldapConn, ldap_result_msg); 00366 00367 for (tot_count = 0; ldap_entry; tot_count++){ 00368 struct ast_variable *tmp = realtime_ldap_entry_to_var(table_config, ldap_entry); 00369 tot_count += semicolon_count_var(tmp); 00370 ldap_entry = ldap_next_entry(ldapConn, ldap_entry); 00371 ast_variables_destroy(tmp); 00372 } 00373 00374 if (entries_count_ptr) 00375 *entries_count_ptr = tot_count; 00376 /* Now that we have the total count we allocate space and create the variables 00377 * Remember that each element in vars is a linked list that points to realtime variable. 00378 * If the we are dealing with a static realtime variable we create a new element in the \a vars array for each delimited 00379 * 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. 00380 * This memory must be freed outside of this function. */ 00381 vars = ast_calloc(sizeof(struct ast_variable *), tot_count + 1); 00382 00383 ldap_entry = ldap_first_entry(ldapConn, ldap_result_msg); 00384 00385 i = 0; 00386 00387 /* For each static realtime variable we may create several entries in the \a vars array if it's delimited */ 00388 for (entry_index = 0; ldap_entry; ) { 00389 int pos = 0; 00390 delim_value = NULL; 00391 delim_tot_count = 0; 00392 delim_count = 0; 00393 00394 do { /* while delim_count */ 00395 00396 /* Starting new static var */ 00397 char *ldap_attribute_name = ldap_first_attribute(ldapConn, ldap_entry, &ber); 00398 struct berval *value; 00399 while (ldap_attribute_name) { 00400 00401 const char *attribute_name = 00402 convert_attribute_name_from_ldap(table_config, ldap_attribute_name); 00403 int is_realmed_password_attribute = strcasecmp(attribute_name, "md5secret") == 0; 00404 struct berval **values = NULL; 00405 00406 values = ldap_get_values_len(ldapConn, ldap_entry, ldap_attribute_name); 00407 if (values) { 00408 struct berval **v; 00409 char *valptr; 00410 00411 for (v = values; *v; v++) { 00412 value = *v; 00413 valptr = value->bv_val; 00414 if (is_realmed_password_attribute) { 00415 if (strncasecmp(valptr, "{md5}", 5) == 0) { 00416 valptr += 5; 00417 } else { 00418 valptr = NULL; 00419 } 00420 ast_debug(2, "md5: %s\n", valptr); 00421 } 00422 if (valptr) { 00423 if (delim_value == NULL 00424 && !is_realmed_password_attribute 00425 && (static_table_config != table_config || strcmp(attribute_name, "variable_value") == 0)) { 00426 00427 delim_value = ast_strdup(valptr); 00428 00429 if ((delim_tot_count = semicolon_count_str(delim_value)) > 0) { 00430 ast_debug(4, "LINE(%d) is delimited %d times: %s\n", __LINE__, delim_tot_count, delim_value); 00431 is_delimited = 1; 00432 } 00433 } 00434 00435 if (is_delimited != 0 00436 && !is_realmed_password_attribute 00437 && (static_table_config != table_config || strcmp(attribute_name, "variable_value") == 0) ) { 00438 /* for non-Static RealTime, first */ 00439 00440 for (i = pos; !ast_strlen_zero(valptr + i); i++) { 00441 ast_debug(4, "LINE(%d) DELIM pos: %d i: %d\n", __LINE__, pos, i); 00442 if (delim_value[i] == ';') { 00443 delim_value[i] = '\0'; 00444 00445 ast_debug(2, "LINE(%d) DELIM - attribute_name: %s value: %s pos: %d\n", __LINE__, attribute_name, &delim_value[pos], pos); 00446 00447 if (prev) { 00448 prev->next = ast_variable_new(attribute_name, &delim_value[pos], table_config->table_name); 00449 if (prev->next) { 00450 prev = prev->next; 00451 } 00452 } else { 00453 prev = var = ast_variable_new(attribute_name, &delim_value[pos], table_config->table_name); 00454 } 00455 pos = i + 1; 00456 00457 if (static_table_config == table_config) { 00458 break; 00459 } 00460 } 00461 } 00462 if (ast_strlen_zero(valptr + i)) { 00463 ast_debug(4, "LINE(%d) DELIM pos: %d i: %d delim_count: %d\n", __LINE__, pos, i, delim_count); 00464 /* Last delimited value */ 00465 ast_debug(4, "LINE(%d) DELIM - attribute_name: %s value: %s pos: %d\n", __LINE__, attribute_name, &delim_value[pos], pos); 00466 if (prev) { 00467 prev->next = ast_variable_new(attribute_name, &delim_value[pos], table_config->table_name); 00468 if (prev->next) { 00469 prev = prev->next; 00470 } 00471 } else { 00472 prev = var = ast_variable_new(attribute_name, &delim_value[pos], table_config->table_name); 00473 } 00474 /* Remembering to free memory */ 00475 is_delimited = 0; 00476 pos = 0; 00477 } 00478 free(delim_value); 00479 delim_value = NULL; 00480 00481 ast_debug(4, "LINE(%d) DELIM pos: %d i: %d\n", __LINE__, pos, i); 00482 } else { 00483 /* not delimited */ 00484 if (delim_value) { 00485 free(delim_value); 00486 delim_value = NULL; 00487 } 00488 ast_debug(2, "LINE(%d) attribute_name: %s value: %s\n", __LINE__, attribute_name, valptr); 00489 00490 if (prev) { 00491 prev->next = ast_variable_new(attribute_name, valptr, table_config->table_name); 00492 if (prev->next) { 00493 prev = prev->next; 00494 } 00495 } else { 00496 prev = var = ast_variable_new(attribute_name, valptr, table_config->table_name); 00497 } 00498 } 00499 } 00500 } /*!< for (v = values; *v; v++) */ 00501 ldap_value_free_len(values); 00502 }/*!< if (values) */ 00503 ldap_attribute_name = ldap_next_attribute(ldapConn, ldap_entry, ber); 00504 } /*!< while (ldap_attribute_name) */ 00505 ber_free(ber, 0); 00506 if (static_table_config == table_config) { 00507 if (option_debug > 2) { 00508 const struct ast_variable *tmpdebug = variable_named(var, "variable_name"); 00509 const struct ast_variable *tmpdebug2 = variable_named(var, "variable_value"); 00510 if (tmpdebug && tmpdebug2) { 00511 ast_debug(3, "LINE(%d) Added to vars - %s = %s\n", __LINE__, tmpdebug->value, tmpdebug2->value); 00512 } 00513 } 00514 vars[entry_index++] = var; 00515 prev = NULL; 00516 } 00517 00518 delim_count++; 00519 } while (delim_count <= delim_tot_count && static_table_config == table_config); 00520 00521 if (static_table_config != table_config) { 00522 ast_debug(3, "LINE(%d) Added to vars - non static\n", __LINE__); 00523 00524 vars[entry_index++] = var; 00525 prev = NULL; 00526 } 00527 ldap_entry = ldap_next_entry(ldapConn, ldap_entry); 00528 } /*!< end for loop over ldap_entry */ 00529 00530 return vars; 00531 }
| static char * realtime_ldap_status | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 1716 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.
01717 { 01718 char status[256], credentials[100] = ""; 01719 int ctimesec = time(NULL) - connect_time; 01720 01721 switch (cmd) { 01722 case CLI_INIT: 01723 e->command = "realtime show ldap status"; 01724 e->usage = 01725 "Usage: realtime show ldap status\n" 01726 " Shows connection information for the LDAP RealTime driver\n"; 01727 return NULL; 01728 case CLI_GENERATE: 01729 return NULL; 01730 } 01731 01732 if (!ldapConn) 01733 return CLI_FAILURE; 01734 01735 if (!ast_strlen_zero(url)) 01736 snprintf(status, sizeof(status), "Connected to '%s', baseDN %s", url, base_distinguished_name); 01737 01738 if (!ast_strlen_zero(user)) 01739 snprintf(credentials, sizeof(credentials), " with username %s", user); 01740 01741 if (ctimesec > 31536000) { 01742 ast_cli(a->fd, "%s%s for %d years, %d days, %d hours, %d minutes, %d seconds.\n", 01743 status, credentials, ctimesec / 31536000, 01744 (ctimesec % 31536000) / 86400, (ctimesec % 86400) / 3600, 01745 (ctimesec % 3600) / 60, ctimesec % 60); 01746 } else if (ctimesec > 86400) { 01747 ast_cli(a->fd, "%s%s for %d days, %d hours, %d minutes, %d seconds.\n", 01748 status, credentials, ctimesec / 86400, (ctimesec % 86400) / 3600, 01749 (ctimesec % 3600) / 60, ctimesec % 60); 01750 } else if (ctimesec > 3600) { 01751 ast_cli(a->fd, "%s%s for %d hours, %d minutes, %d seconds.\n", 01752 status, credentials, ctimesec / 3600, (ctimesec % 3600) / 60, 01753 ctimesec % 60); 01754 } else if (ctimesec > 60) { 01755 ast_cli(a->fd, "%s%s for %d minutes, %d seconds.\n", status, credentials, 01756 ctimesec / 60, ctimesec % 60); 01757 } else { 01758 ast_cli(a->fd, "%s%s for %d seconds.\n", status, credentials, ctimesec); 01759 } 01760 01761 return CLI_SUCCESS; 01762 }
| 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 938 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.
00940 { 00941 struct ast_variable **vars = 00942 realtime_ldap_base_ap(NULL, basedn, table_name, ap); 00943 struct ast_config *cfg = NULL; 00944 00945 if (vars) { 00946 cfg = ast_config_new(); 00947 if (!cfg) { 00948 ast_log(LOG_ERROR, "Unable to create a config!\n"); 00949 } else { 00950 struct ast_variable **p = vars; 00951 00952 while (*p) { 00953 struct ast_category *cat = NULL; 00954 cat = ast_category_new("", table_name, -1); 00955 if (!cat) { 00956 ast_log(LOG_ERROR, "Unable to create a new category!\n"); 00957 break; 00958 } else { 00959 struct ast_variable *var = *p; 00960 while (var) { 00961 struct ast_variable *next = var->next; 00962 var->next = NULL; 00963 ast_variable_append(cat, var); 00964 var = next; 00965 } 00966 } 00967 ast_category_append(cfg, cat); 00968 p++; 00969 } 00970 } 00971 free(vars); 00972 } 00973 return cfg; 00974 00975 }
| static int reload | ( | void | ) | [static] |
Definition at line 1549 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().
01550 { 01551 /* Aquire control before doing anything to the module itself. */ 01552 ast_mutex_lock(&ldap_lock); 01553 01554 if (ldapConn) { 01555 ldap_unbind_ext_s(ldapConn, NULL, NULL); 01556 ldapConn = NULL; 01557 } 01558 01559 if (parse_config() < 0) { 01560 ast_log(LOG_NOTICE, "Cannot reload LDAP RealTime driver.\n"); 01561 ast_mutex_unlock(&ldap_lock); 01562 return 0; 01563 } 01564 01565 if (!ldap_reconnect()) 01566 ast_log(LOG_WARNING, "Couldn't establish connection. Check debug.\n"); 01567 01568 ast_verb(2, "LDAP RealTime reloaded.\n"); 01569 01570 /* Done reloading. Release lock so others can now use driver. */ 01571 ast_mutex_unlock(&ldap_lock); 01572 01573 return 0; 01574 }
| static int replace_string_in_string | ( | char * | string, | |
| const char * | search, | |||
| const char * | by | |||
| ) | [static] |
Replace <search> by <by> in string. No check is done on string allocated size !
Definition at line 662 of file res_config_ldap.c.
Referenced by append_var_and_value_to_filter().
00663 { 00664 int search_len = strlen(search); 00665 int by_len = strlen(by); 00666 int replaced = 0; 00667 char *p = strstr(string, search); 00668 if (p) { 00669 replaced = 1; 00670 while (p) { 00671 if (by_len == search_len) 00672 memcpy(p, by, by_len); 00673 else { 00674 memmove(p + by_len, p + search_len, 00675 strlen(p + search_len) + 1); 00676 memcpy(p, by, by_len); 00677 } 00678 p = strstr(p + by_len, search); 00679 } 00680 } 00681 return replaced; 00682 }
| 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().
| 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 ast_debug(1, "LINE(%d) semicolon_count_var: %s\n", __LINE__, var_value->value); 00175 00176 return semicolon_count_str(var_value->value); 00177 }
| static char* substituted | ( | struct ast_channel * | channel, | |
| const char * | string | |||
| ) | [static] |
caller should free returned pointer
Definition at line 620 of file res_config_ldap.c.
References ast_calloc, ast_debug, ast_strlen_zero(), MAXRESULT, and pbx_substitute_variables_helper().
Referenced by cleaned_basedn().
00621 { 00622 #define MAXRESULT 2048 00623 char *ret_string = NULL; 00624 00625 if (!ast_strlen_zero(string)) { 00626 ret_string = ast_calloc(1, MAXRESULT); 00627 pbx_substitute_variables_helper(channel, string, ret_string, MAXRESULT - 1); 00628 } 00629 ast_debug(2, "substituted: string: '%s' => '%s' \n", 00630 string, ret_string); 00631 return ret_string; 00632 }
| 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 198 of file res_config_ldap.c.
References ldap_table_config::additional_filter, 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().
00199 { 00200 struct ldap_table_config *c; 00201 00202 while ((c = AST_LIST_REMOVE_HEAD(&table_configs, entry))) { 00203 if (c->table_name) 00204 free(c->table_name); 00205 if (c->additional_filter) 00206 free(c->additional_filter); 00207 if (c->attributes) 00208 ast_variables_destroy(c->attributes); 00209 free(c); 00210 } 00211 00212 base_table_config = NULL; 00213 static_table_config = NULL; 00214 }
| static int unload_module | ( | void | ) | [static] |
Definition at line 1528 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().
01529 { 01530 /* Aquire control before doing anything to the module itself. */ 01531 ast_mutex_lock(&ldap_lock); 01532 01533 table_configs_free(); 01534 01535 if (ldapConn) { 01536 ldap_unbind_ext_s(ldapConn, NULL, NULL); 01537 ldapConn = NULL; 01538 } 01539 ast_cli_unregister_multiple(ldap_cli, ARRAY_LEN(ldap_cli)); 01540 ast_config_engine_deregister(&ldap_engine); 01541 ast_verb(1, "LDAP RealTime unloaded.\n"); 01542 01543 /* Unlock so something else can destroy the lock. */ 01544 ast_mutex_unlock(&ldap_lock); 01545 01546 return 0; 01547 }
| static int update2_ldap | ( | const char * | basedn, | |
| const char * | table_name, | |||
| va_list | ap | |||
| ) | [static] |
Definition at line 1314 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().
01315 { 01316 int error = 0; 01317 LDAPMessage *ldap_entry = NULL; 01318 LDAPMod **ldap_mods; 01319 const char *newparam = NULL; 01320 const char *newval = NULL; 01321 char *dn; 01322 int num_entries = 0; 01323 int i = 0; 01324 int mods_size = 0; 01325 int mod_exists = 0; 01326 struct ldap_table_config *table_config = NULL; 01327 char *clean_basedn = NULL; 01328 struct ast_str *filter = NULL; 01329 int tries = 0; 01330 int result = 0; 01331 LDAPMessage *ldap_result_msg = NULL; 01332 01333 if (!table_name) { 01334 ast_log(LOG_WARNING, "No table_name specified.\n"); 01335 return -1; 01336 } 01337 01338 if (!(filter = ast_str_create(80))) 01339 return -1; 01340 01341 ast_mutex_lock(&ldap_lock); 01342 01343 /* We now have our complete statement; Lets connect to the server and execute it. */ 01344 if (!ldap_reconnect()) { 01345 ast_mutex_unlock(&ldap_lock); 01346 ast_free(filter); 01347 return -1; 01348 } 01349 01350 table_config = table_config_for_table_name(table_name); 01351 if (!table_config) { 01352 ast_log(LOG_WARNING, "No table named '%s'.\n", table_name); 01353 ast_mutex_unlock(&ldap_lock); 01354 ast_free(filter); 01355 return -1; 01356 } 01357 01358 clean_basedn = cleaned_basedn(NULL, basedn); 01359 01360 /* Create the filter with the table additional filter and the parameter/value pairs we were given */ 01361 ast_str_append(&filter, 0, "(&"); 01362 if (table_config && table_config->additional_filter) { 01363 ast_str_append(&filter, 0, "%s", table_config->additional_filter); 01364 } 01365 if (table_config != base_table_config && base_table_config 01366 && base_table_config->additional_filter) { 01367 ast_str_append(&filter, 0, "%s", base_table_config->additional_filter); 01368 } 01369 01370 /* Get multiple lookup keyfields and values */ 01371 while ((newparam = va_arg(ap, const char *))) { 01372 newval = va_arg(ap, const char *); 01373 append_var_and_value_to_filter(&filter, table_config, newparam, newval); 01374 } 01375 ast_str_append(&filter, 0, ")"); 01376 01377 /* Create the modification array with the parameter/value pairs we were given, 01378 * if there are several parameters with the same name, we collect them into 01379 * one parameter/value pair and delimit them with a semicolon */ 01380 newparam = va_arg(ap, const char *); 01381 newparam = convert_attribute_name_to_ldap(table_config, newparam); 01382 newval = va_arg(ap, const char *); 01383 if (!newparam || !newval) { 01384 ast_log(LOG_WARNING, 01385 "LINE(%d): need at least one parameter to modify.\n", __LINE__); 01386 ast_free(filter); 01387 ast_free(clean_basedn); 01388 return -1; 01389 } 01390 01391 mods_size = 2; /* one for the first param/value pair and one for the the terminating NULL */ 01392 ldap_mods = ast_calloc(sizeof(LDAPMod *), mods_size); 01393 ldap_mods[0] = ast_calloc(1, sizeof(LDAPMod)); 01394 01395 ldap_mods[0]->mod_op = LDAP_MOD_REPLACE; 01396 ldap_mods[0]->mod_type = ast_calloc(sizeof(char), strlen(newparam) + 1); 01397 strcpy(ldap_mods[0]->mod_type, newparam); 01398 01399 ldap_mods[0]->mod_values = ast_calloc(sizeof(char), 2); 01400 ldap_mods[0]->mod_values[0] = ast_calloc(sizeof(char), strlen(newval) + 1); 01401 strcpy(ldap_mods[0]->mod_values[0], newval); 01402 01403 while ((newparam = va_arg(ap, const char *))) { 01404 newparam = convert_attribute_name_to_ldap(table_config, newparam); 01405 newval = va_arg(ap, const char *); 01406 mod_exists = 0; 01407 01408 for (i = 0; i < mods_size - 1; i++) { 01409 if (ldap_mods[i]&& !strcmp(ldap_mods[i]->mod_type, newparam)) { 01410 /* We have the parameter allready, adding the value as a semicolon delimited value */ 01411 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)); 01412 strcat(ldap_mods[i]->mod_values[0], ";"); 01413 strcat(ldap_mods[i]->mod_values[0], newval); 01414 mod_exists = 1; 01415 break; 01416 } 01417 } 01418 01419 /* create new mod */ 01420 if (!mod_exists) { 01421 mods_size++; 01422 ldap_mods = ast_realloc(ldap_mods, sizeof(LDAPMod *) * mods_size); 01423 ldap_mods[mods_size - 1] = NULL; 01424 ldap_mods[mods_size - 2] = ast_calloc(1, sizeof(LDAPMod)); 01425 01426 ldap_mods[mods_size - 2]->mod_op = LDAP_MOD_REPLACE; 01427 01428 ldap_mods[mods_size - 2]->mod_type = ast_calloc(sizeof(char), strlen(newparam) + 1); 01429 strcpy(ldap_mods[mods_size - 2]->mod_type, newparam); 01430 01431 ldap_mods[mods_size - 2]->mod_values = ast_calloc(sizeof(char *), 2); 01432 ldap_mods[mods_size - 2]->mod_values[0] = ast_calloc(sizeof(char), strlen(newval) + 1); 01433 strcpy(ldap_mods[mods_size - 2]->mod_values[0], newval); 01434 } 01435 } 01436 /* freeing ldap_mods further down */ 01437 01438 do { 01439 /* freeing ldap_result further down */ 01440 result = ldap_search_ext_s(ldapConn, clean_basedn, 01441 LDAP_SCOPE_SUBTREE, ast_str_buffer(filter), NULL, 0, NULL, NULL, NULL, LDAP_NO_LIMIT, 01442 &ldap_result_msg); 01443 if (result != LDAP_SUCCESS && is_ldap_connect_error(result)) { 01444 ast_log(LOG_WARNING, "Failed to query database. Try %d/3\n", 01445 tries + 1); 01446 tries++; 01447 if (tries < 3) { 01448 usleep(500000L * tries); 01449 if (ldapConn) { 01450 ldap_unbind_ext_s(ldapConn, NULL, NULL); 01451 ldapConn = NULL; 01452 } 01453 if (!ldap_reconnect()) 01454 break; 01455 } 01456 } 01457 } while (result != LDAP_SUCCESS && tries < 3 && is_ldap_connect_error(result)); 01458 01459 if (result != LDAP_SUCCESS) { 01460 ast_log(LOG_WARNING, "Failed to query directory. Check debug for more info.\n"); 01461 ast_log(LOG_WARNING, "Query: %s\n", ast_str_buffer(filter)); 01462 ast_log(LOG_WARNING, "Query Failed because: %s\n", 01463 ldap_err2string(result)); 01464 01465 ast_mutex_unlock(&ldap_lock); 01466 free(filter); 01467 free(clean_basedn); 01468 ldap_msgfree(ldap_result_msg); 01469 ldap_mods_free(ldap_mods, 0); 01470 return -1; 01471 } 01472 /* Ready to update */ 01473 if ((num_entries = ldap_count_entries(ldapConn, ldap_result_msg)) > 0) { 01474 for (i = 0; option_debug > 2 && i < mods_size - 1; i++) 01475 ast_debug(3, "LINE(%d) %s=%s \n", __LINE__, ldap_mods[i]->mod_type, ldap_mods[i]->mod_values[0]); 01476 01477 ldap_entry = ldap_first_entry(ldapConn, ldap_result_msg); 01478 01479 for (i = 0; ldap_entry; i++) { 01480 dn = ldap_get_dn(ldapConn, ldap_entry); 01481 if ((error = ldap_modify_ext_s(ldapConn, dn, ldap_mods, NULL, NULL)) != LDAP_SUCCESS) 01482 ast_log(LOG_ERROR, "Couldn't modify dn:%s because %s", dn, ldap_err2string(error)); 01483 01484 ldap_entry = ldap_next_entry(ldapConn, ldap_entry); 01485 } 01486 } 01487 01488 ast_mutex_unlock(&ldap_lock); 01489 if (filter) 01490 free(filter); 01491 if (clean_basedn) 01492 free(clean_basedn); 01493 ldap_msgfree(ldap_result_msg); 01494 ldap_mods_free(ldap_mods, 0); 01495 return num_entries; 01496 }
| static int update_ldap | ( | const char * | basedn, | |
| const char * | table_name, | |||
| const char * | attribute, | |||
| const char * | lookup, | |||
| va_list | ap | |||
| ) | [static] |
Definition at line 1127 of file res_config_ldap.c.
References ldap_table_config::additional_filter, append_var_and_value_to_filter(), ast_calloc, ast_debug, 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(), LOG_ERROR, LOG_WARNING, option_debug, and table_config_for_table_name().
01129 { 01130 int error = 0; 01131 LDAPMessage *ldap_entry = NULL; 01132 LDAPMod **ldap_mods; 01133 const char *newparam = NULL; 01134 const char *newval = NULL; 01135 char *dn; 01136 int num_entries = 0; 01137 int i = 0; 01138 int mods_size = 0; 01139 int mod_exists = 0; 01140 struct ldap_table_config *table_config = NULL; 01141 char *clean_basedn = NULL; 01142 struct ast_str *filter = NULL; 01143 int tries = 0; 01144 int result = 0; 01145 LDAPMessage *ldap_result_msg = NULL; 01146 01147 if (!table_name) { 01148 ast_log(LOG_WARNING, "No table_name specified.\n"); 01149 return -1; 01150 } 01151 01152 if (!(filter = ast_str_create(80))) 01153 return -1; 01154 01155 if (!attribute || !lookup) { 01156 ast_log(LOG_WARNING, 01157 "LINE(%d): search parameters are empty.\n", __LINE__); 01158 return -1; 01159 } 01160 ast_mutex_lock(&ldap_lock); 01161 01162 /* We now have our complete statement; Lets connect to the server and execute it. */ 01163 if (!ldap_reconnect()) { 01164 ast_mutex_unlock(&ldap_lock); 01165 return -1; 01166 } 01167 01168 table_config = table_config_for_table_name(table_name); 01169 if (!table_config) { 01170 ast_log(LOG_WARNING, "No table named '%s'.\n", table_name); 01171 ast_mutex_unlock(&ldap_lock); 01172 return -1; 01173 } 01174 01175 clean_basedn = cleaned_basedn(NULL, basedn); 01176 01177 /* Create the filter with the table additional filter and the parameter/value pairs we were given */ 01178 ast_str_append(&filter, 0, "(&"); 01179 if (table_config && table_config->additional_filter) { 01180 ast_str_append(&filter, 0, "%s", table_config->additional_filter); 01181 } 01182 if (table_config != base_table_config && base_table_config 01183 && base_table_config->additional_filter) { 01184 ast_str_append(&filter, 0, "%s", base_table_config->additional_filter); 01185 } 01186 append_var_and_value_to_filter(&filter, table_config, attribute, lookup); 01187 ast_str_append(&filter, 0, ")"); 01188 01189 /* Create the modification array with the parameter/value pairs we were given, 01190 * if there are several parameters with the same name, we collect them into 01191 * one parameter/value pair and delimit them with a semicolon */ 01192 newparam = va_arg(ap, const char *); 01193 newparam = convert_attribute_name_to_ldap(table_config, newparam); 01194 newval = va_arg(ap, const char *); 01195 if (!newparam || !newval) { 01196 ast_log(LOG_WARNING, 01197 "LINE(%d): need at least one parameter to modify.\n", __LINE__); 01198 return -1; 01199 } 01200 01201 mods_size = 2; /* one for the first param/value pair and one for the the terminating NULL */ 01202 ldap_mods = ast_calloc(sizeof(LDAPMod *), mods_size); 01203 ldap_mods[0] = ast_calloc(1, sizeof(LDAPMod)); 01204 01205 ldap_mods[0]->mod_op = LDAP_MOD_REPLACE; 01206 ldap_mods[0]->mod_type = ast_strdup(newparam); 01207 01208 ldap_mods[0]->mod_values = ast_calloc(sizeof(char *), 2); 01209 ldap_mods[0]->mod_values[0] = ast_strdup(newval); 01210 01211 while ((newparam = va_arg(ap, const char *))) { 01212 newparam = convert_attribute_name_to_ldap(table_config, newparam); 01213 newval = va_arg(ap, const char *); 01214 mod_exists = 0; 01215 01216 for (i = 0; i < mods_size - 1; i++) { 01217 if (ldap_mods[i]&& !strcmp(ldap_mods[i]->mod_type, newparam)) { 01218 /* We have the parameter allready, adding the value as a semicolon delimited value */ 01219 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)); 01220 strcat(ldap_mods[i]->mod_values[0], ";"); 01221 strcat(ldap_mods[i]->mod_values[0], newval); 01222 mod_exists = 1; 01223 break; 01224 } 01225 } 01226 01227 /* create new mod */ 01228 if (!mod_exists) { 01229 mods_size++; 01230 ldap_mods = ast_realloc(ldap_mods, sizeof(LDAPMod *) * mods_size); 01231 ldap_mods[mods_size - 1] = NULL; 01232 01233 ldap_mods[mods_size - 2] = ast_calloc(1, sizeof(LDAPMod)); 01234 01235 ldap_mods[mods_size - 2]->mod_type = ast_calloc(sizeof(char), strlen(newparam) + 1); 01236 strcpy(ldap_mods[mods_size - 2]->mod_type, newparam); 01237 01238 if (strlen(newval) == 0) { 01239 ldap_mods[mods_size - 2]->mod_op = LDAP_MOD_DELETE; 01240 } else { 01241 ldap_mods[mods_size - 2]->mod_op = LDAP_MOD_REPLACE; 01242 01243 ldap_mods[mods_size - 2]->mod_values = ast_calloc(sizeof(char *), 2); 01244 ldap_mods[mods_size - 2]->mod_values[0] = ast_calloc(sizeof(char), strlen(newval) + 1); 01245 strcpy(ldap_mods[mods_size - 2]->mod_values[0], newval); 01246 } 01247 } 01248 } 01249 /* freeing ldap_mods further down */ 01250 01251 do { 01252 /* freeing ldap_result further down */ 01253 result = ldap_search_ext_s(ldapConn, clean_basedn, 01254 LDAP_SCOPE_SUBTREE, ast_str_buffer(filter), NULL, 0, NULL, NULL, NULL, LDAP_NO_LIMIT, 01255 &ldap_result_msg); 01256 if (result != LDAP_SUCCESS && is_ldap_connect_error(result)) { 01257 ast_log(LOG_WARNING, "Failed to query database. Try %d/3\n", 01258 tries + 1); 01259 tries++; 01260 if (tries < 3) { 01261 usleep(500000L * tries); 01262 if (ldapConn) { 01263 ldap_unbind_ext_s(ldapConn, NULL, NULL); 01264 ldapConn = NULL; 01265 } 01266 if (!ldap_reconnect()) 01267 break; 01268 } 01269 } 01270 } while (result != LDAP_SUCCESS && tries < 3 && is_ldap_connect_error(result)); 01271 01272 if (result != LDAP_SUCCESS) { 01273 ast_log(LOG_WARNING, "Failed to query directory. Check debug for more info.\n"); 01274 ast_log(LOG_WARNING, "Query: %s\n", ast_str_buffer(filter)); 01275 ast_log(LOG_WARNING, "Query Failed because: %s\n", 01276 ldap_err2string(result)); 01277 01278 ast_mutex_unlock(&ldap_lock); 01279 free(filter); 01280 free(clean_basedn); 01281 ldap_msgfree(ldap_result_msg); 01282 ldap_mods_free(ldap_mods, 0); 01283 return -1; 01284 } 01285 /* Ready to update */ 01286 if ((num_entries = ldap_count_entries(ldapConn, ldap_result_msg)) > 0) { 01287 ast_debug(3, "LINE(%d) Modifying %s=%s hits: %d\n", __LINE__, attribute, lookup, num_entries); 01288 for (i = 0; option_debug > 2 && i < mods_size - 1; i++) { 01289 if (ldap_mods[i]->mod_op != LDAP_MOD_DELETE) { 01290 ast_debug(3, "LINE(%d) %s=%s \n", __LINE__, ldap_mods[i]->mod_type, ldap_mods[i]->mod_values[0]); 01291 } else { 01292 ast_debug(3, "LINE(%d) deleting %s \n", __LINE__, ldap_mods[i]->mod_type); 01293 } 01294 } 01295 ldap_entry = ldap_first_entry(ldapConn, ldap_result_msg); 01296 01297 for (i = 0; ldap_entry; i++) { 01298 dn = ldap_get_dn(ldapConn, ldap_entry); 01299 if ((error = ldap_modify_ext_s(ldapConn, dn, ldap_mods, NULL, NULL)) != LDAP_SUCCESS) 01300 ast_log(LOG_ERROR, "Couldn't modify dn:%s because %s", dn, ldap_err2string(error)); 01301 01302 ldap_entry = ldap_next_entry(ldapConn, ldap_entry); 01303 } 01304 } 01305 01306 ast_mutex_unlock(&ldap_lock); 01307 free(filter); 01308 free(clean_basedn); 01309 ldap_msgfree(ldap_result_msg); 01310 ldap_mods_free(ldap_mods, 0); 01311 return num_entries; 01312 }
| 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().
struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_GLOBAL_SYMBOLS , .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 = "0901e4e500243c855563a2d78b0c03e4" , .load = load_module, .unload = unload_module, .reload = reload, } [static] |
Definition at line 1768 of file res_config_ldap.c.
struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 1768 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.
struct ast_cli_entry ldap_cli[] [static] |
{
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 1498 of file res_config_ldap.c.
Referenced by load_module(), and unload_module().
ast_mutex_t ldap_lock = ((ast_mutex_t) PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP ) [static] |
Definition at line 63 of file res_config_ldap.c.
Referenced by ldap_loadentry(), load_module(), realtime_ldap_base_ap(), reload(), unload_module(), update2_ldap(), and update_ldap().
LDAP* ldapConn [static] |
Definition at line 65 of file res_config_ldap.c.
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_exec(), dial_exec_full(), 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.
Referenced by add_sdp(), aji_dinfo_handler(), ast_readconfig(), ast_remotecontrol(), ast_rtp_read(), ast_var_Version(), check_access(), config_module(), manager_modulecheck(), and update_registry().
1.6.2