#include "asterisk.h"
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <ldap.h>
#include "asterisk/channel.h"
#include "asterisk/logger.h"
#include "asterisk/config.h"
#include "asterisk/module.h"
#include "asterisk/lock.h"
#include "asterisk/options.h"
#include "asterisk/cli.h"
#include "asterisk/utils.h"
#include "asterisk/strings.h"
#include "asterisk/pbx.h"
#include "asterisk/linkedlists.h"

Go to the source code of this file.
Data Structures | |
| struct | category_and_metric |
| struct | ldap_table_config |
| Table configuration. More... | |
| struct | table_configs |
| Should be locked before using it. More... | |
Defines | |
| #define | MAXRESULT 2048 |
| #define | RES_CONFIG_LDAP_CONF "res_ldap.conf" |
| #define | RES_CONFIG_LDAP_DEFAULT_BASEDN "asterisk" |
Functions | |
| static void | __reg_module (void) |
| static void | __unreg_module (void) |
| static void | append_var_and_value_to_filter (struct ast_str **filter, struct ldap_table_config *table_config, const char *name, const char *value) |
| Append a name=value filter string. The filter string can grow. | |
| static char * | cleaned_basedn (struct ast_channel *channel, const char *basedn) |
| static int | compare_categories (const void *a, const void *b) |
| Sorting alogrithm for qsort to find the order of the variables a and b. | |
| static struct ast_config * | config_ldap (const char *basedn, const char *table_name, const char *file, struct ast_config *cfg, struct ast_flags config_flags, const char *sugg_incl, const char *who_asked) |
| See Asterisk doc. | |
| static const char * | convert_attribute_name_from_ldap (struct ldap_table_config *table_config, const char *attribute_name) |
| Convert ldap attribute name to variable name. | |
| static const char * | convert_attribute_name_to_ldap (struct ldap_table_config *table_config, const char *attribute_name) |
| Convert variable name to ldap attribute name - Should be locked before using it. | |
| static int | is_ldap_connect_error (int err) |
| Check if we have a connection error. | |
| static struct ast_variable * | ldap_loadentry (struct ldap_table_config *table_config, const char *dn) |
| Get LDAP entry by dn and return attributes as variables - Should be locked before using it This is used for setting the default values of an object(i.e., with accountBaseDN). | |
| static int | ldap_reconnect (void) |
| static void | ldap_table_config_add_attribute (struct ldap_table_config *table_config, const char *attribute_name, const char *attribute_value) |
| add attribute to table config - Should be locked before using it | |
| static int | load_module (void) |
| static int | parse_config (void) |
| parse the configuration file | |
| static struct ast_variable * | realtime_ldap (const char *basedn, const char *table_name, va_list ap) |
| See Asterisk doc. | |
| static struct ast_variable ** | realtime_ldap_base (unsigned int *entries_count_ptr, const char *basedn, const char *table_name,...) |
| same as realtime_ldap_base_ap but take variable arguments count list | |
| static struct ast_variable ** | realtime_ldap_base_ap (unsigned int *entries_count_ptr, const char *basedn, const char *table_name, va_list ap) |
| LDAP base function. | |
| static struct ast_variable * | realtime_ldap_entry_to_var (struct ldap_table_config *table_config, LDAPMessage *ldap_entry) |
| Get variables from ldap entry attributes. | |
| static struct ast_variable ** | realtime_ldap_result_to_vars (struct ldap_table_config *table_config, LDAPMessage *ldap_result_msg, unsigned int *entries_count_ptr) |
| Get variables from ldap entry attributes - Should be locked before using it. | |
| static char * | realtime_ldap_status (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| static struct ast_config * | realtime_multi_ldap (const char *basedn, const char *table_name, va_list ap) |
| See Asterisk doc. | |
| static int | reload (void) |
| static int | replace_string_in_string (char *string, const char *search, const char *by) |
| Replace <search> by <by> in string. | |
| static int | semicolon_count_str (const char *somestr) |
| for the semicolon delimiter | |
| static int | semicolon_count_var (struct ast_variable *var) |
| static char * | substituted (struct ast_channel *channel, const char *string) |
| static struct ldap_table_config * | table_config_for_table_name (const char *table_name) |
| Find a table_config - Should be locked before using it. | |
| static struct ldap_table_config * | table_config_new (const char *table_name) |
| Create a new table_config. | |
| static void | table_configs_free (void) |
| Free table_config. | |
| static int | unload_module (void) |
| static int | update2_ldap (const char *basedn, const char *table_name, va_list ap) |
| static int | update_ldap (const char *basedn, const char *table_name, const char *attribute, const char *lookup, va_list ap) |
| static struct ast_variable * | variable_named (struct ast_variable *var, const char *name) |
| Find variable by name. | |
Variables | |
| static struct ast_module_info | __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "LDAP realtime interface" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_REALTIME_DRIVER, } |
| static struct ast_module_info * | ast_module_info = &__mod_info |
| static char | base_distinguished_name [512] |
| static struct ldap_table_config * | base_table_config |
| static time_t | connect_time |
| static struct ast_cli_entry | ldap_cli [] |
| static struct ast_config_engine | ldap_engine |
| static ast_mutex_t | ldap_lock = { PTHREAD_MUTEX_INITIALIZER , NULL, 1 } |
| static LDAP * | ldapConn |
| static char | pass [512] |
| static struct ldap_table_config * | static_table_config |
| static char | url [512] |
| static char | user [512] |
| static int | version |
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 1816 of file res_config_ldap.c.
| static void __unreg_module | ( | void | ) | [static] |
Definition at line 1816 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 1025 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().
01026 { 01027 const struct category_and_metric *as = a; 01028 const struct category_and_metric *bs = b; 01029 01030 if (as->metric < bs->metric) { 01031 return -1; 01032 } else if (as->metric > bs->metric) { 01033 return 1; 01034 } else if (as->metric == bs->metric && strcmp(as->name, bs->name) != 0) { 01035 return strcmp(as->name, bs->name); 01036 } 01037 /* if the metric and the category name is the same, we check the variable metric */ 01038 if (as->var_metric < bs->var_metric) { 01039 return -1; 01040 } else if (as->var_metric > bs->var_metric) { 01041 return 1; 01042 } 01043 01044 return 0; 01045 }
| 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 1054 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.
01056 { 01057 unsigned int vars_count = 0; 01058 struct ast_variable **vars; 01059 int i = 0; 01060 struct ast_variable *new_v = NULL; 01061 struct ast_category *cur_cat = NULL; 01062 const char *last_category = NULL; 01063 int last_category_metric = 0; 01064 struct category_and_metric *categories; 01065 struct ast_variable **p; 01066 01067 if (ast_strlen_zero(file) || !strcasecmp(file, RES_CONFIG_LDAP_CONF)) { 01068 ast_log(LOG_ERROR, "Missing configuration file: %s. Can't configure myself.\n", RES_CONFIG_LDAP_CONF); 01069 return NULL; 01070 } 01071 01072 vars = realtime_ldap_base(&vars_count, basedn, table_name, "filename", file, "commented", "FALSE", NULL); 01073 01074 if (!vars) { 01075 ast_log(LOG_WARNING, "Could not find config '%s' in directory.\n", file); 01076 return NULL; 01077 } 01078 01079 /*!\note Since the items come back in random order, they need to be sorted 01080 * first, and since the data could easily exceed stack size, this is 01081 * allocated from the heap. 01082 */ 01083 if (!(categories = ast_calloc(sizeof(*categories), vars_count))) { 01084 return NULL; 01085 } 01086 01087 for (vars_count = 0, p = vars; *p; p++) { 01088 struct ast_variable *category = variable_named(*p, "category"); 01089 struct ast_variable *cat_metric = variable_named(*p, "cat_metric"); 01090 struct ast_variable *var_name = variable_named(*p, "variable_name"); 01091 struct ast_variable *var_val = variable_named(*p, "variable_value"); 01092 struct ast_variable *var_metric = variable_named(*p, "var_metric"); 01093 struct ast_variable *dn = variable_named(*p, "dn"); 01094 01095 ast_debug(3, "category: %s\n", category->value); 01096 ast_debug(3, "var_name: %s\n", var_name->value); 01097 ast_debug(3, "var_val: %s\n", var_val->value); 01098 ast_debug(3, "cat_metric: %s\n", cat_metric->value); 01099 01100 if (!category) { 01101 ast_log(LOG_ERROR, "No category name in entry '%s' for file '%s'.\n", 01102 (dn ? dn->value : "?"), file); 01103 } else if (!cat_metric) { 01104 ast_log(LOG_ERROR, "No category metric in entry '%s'(category: %s) for file '%s'.\n", 01105 (dn ? dn->value : "?"), category->value, file); 01106 } else if (!var_metric) { 01107 ast_log(LOG_ERROR, "No variable metric in entry '%s'(category: %s) for file '%s'.\n", 01108 (dn ? dn->value : "?"), category->value, file); 01109 } else if (!var_name) { 01110 ast_log(LOG_ERROR, "No variable name in entry '%s' (category: %s metric: %s) for file '%s'.\n", 01111 (dn ? dn->value : "?"), category->value, 01112 cat_metric->value, file); 01113 } else if (!var_val) { 01114 ast_log(LOG_ERROR, "No variable value in entry '%s' (category: %s metric: %s variable: %s) for file '%s'.\n", 01115 (dn ? dn->value : "?"), category->value, 01116 cat_metric->value, var_name->value, file); 01117 } else { 01118 categories[vars_count].name = category->value; 01119 categories[vars_count].metric = atoi(cat_metric->value); 01120 categories[vars_count].variable_name = var_name->value; 01121 categories[vars_count].variable_value = var_val->value; 01122 categories[vars_count].var_metric = atoi(var_metric->value); 01123 vars_count++; 01124 } 01125 } 01126 01127 qsort(categories, vars_count, sizeof(*categories), compare_categories); 01128 01129 for (i = 0; i < vars_count; i++) { 01130 if (!strcmp(categories[i].variable_name, "#include")) { 01131 struct ast_flags flags = { 0 }; 01132 if (!ast_config_internal_load(categories[i].variable_value, cfg, flags, "", who_asked)) { 01133 break; 01134 } 01135 continue; 01136 } 01137 01138 if (!last_category || strcmp(last_category, categories[i].name) || 01139 last_category_metric != categories[i].metric) { 01140 01141 cur_cat = ast_category_new(categories[i].name, table_name, -1); 01142 if (!cur_cat) { 01143 break; 01144 } 01145 last_category = categories[i].name; 01146 last_category_metric = categories[i].metric; 01147 ast_category_append(cfg, cur_cat); 01148 } 01149 01150 if (!(new_v = ast_variable_new(categories[i].variable_name, categories[i].variable_value, table_name))) { 01151 break; 01152 } 01153 01154 ast_variable_append(cur_cat, new_v); 01155 } 01156 01157 ast_free(vars); 01158 ast_free(categories); 01159 01160 return cfg; 01161 }
| static const char* convert_attribute_name_from_ldap | ( | struct ldap_table_config * | table_config, | |
| const char * | attribute_name | |||
| ) | [static] |
Convert ldap attribute name to variable name.
Definition at line 251 of file res_config_ldap.c.
References ARRAY_LEN, ldap_table_config::attributes, base_table_config, ast_variable::name, ast_variable::next, and ast_variable::value.
Referenced by realtime_ldap_entry_to_var(), and realtime_ldap_result_to_vars().
00253 { 00254 int i = 0; 00255 struct ldap_table_config *configs[] = { table_config, base_table_config }; 00256 00257 for (i = 0; i < ARRAY_LEN(configs); i++) { 00258 struct ast_variable *attribute; 00259 00260 if (!configs[i]) { 00261 continue; 00262 } 00263 00264 attribute = configs[i]->attributes; 00265 for (; attribute; attribute = attribute->next) { 00266 if (strcasecmp(attribute_name, attribute->value) == 0) { 00267 return attribute->name; 00268 } 00269 } 00270 } 00271 00272 return attribute_name; 00273 }
| static const char* convert_attribute_name_to_ldap | ( | struct ldap_table_config * | table_config, | |
| const char * | attribute_name | |||
| ) | [static] |
Convert variable name to ldap attribute name - Should be locked before using it.
Definition at line 225 of file res_config_ldap.c.
References ARRAY_LEN, ldap_table_config::attributes, base_table_config, ast_variable::name, ast_variable::next, and ast_variable::value.
Referenced by append_var_and_value_to_filter(), update2_ldap(), and update_ldap().
00227 { 00228 int i = 0; 00229 struct ldap_table_config *configs[] = { table_config, base_table_config }; 00230 00231 for (i = 0; i < ARRAY_LEN(configs); i++) { 00232 struct ast_variable *attribute; 00233 00234 if (!configs[i]) { 00235 continue; 00236 } 00237 00238 attribute = configs[i]->attributes; 00239 for (; attribute; attribute = attribute->next) { 00240 if (!strcasecmp(attribute_name, attribute->name)) { 00241 return attribute->value; 00242 } 00243 } 00244 } 00245 00246 return attribute_name; 00247 }
| static int is_ldap_connect_error | ( | int | err | ) | [static] |
Check if we have a connection error.
Definition at line 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_free, ast_log(), ast_mutex_unlock, 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 directory. 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 directory. 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 00613 /* Only take the first one. */ 00614 var = *vars; 00615 00616 /* Destroy the rest. */ 00617 while (*++p) { 00618 ast_variables_destroy(*p); 00619 } 00620 ast_free(vars); 00621 } 00622 00623 return var; 00624 } 00625 }
| static int ldap_reconnect | ( | void | ) | [static] |
Definition at line 1716 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().
01717 { 01718 int bind_result = 0; 01719 struct berval cred; 01720 01721 if (ldapConn) { 01722 ast_debug(2, "Everything seems fine.\n"); 01723 return 1; 01724 } 01725 01726 if (ast_strlen_zero(url)) { 01727 ast_log(LOG_ERROR, "Not enough parameters to connect to ldap directory\n"); 01728 return 0; 01729 } 01730 01731 if (LDAP_SUCCESS != ldap_initialize(&ldapConn, url)) { 01732 ast_log(LOG_ERROR, "Failed to init ldap connection to '%s'. Check debug for more info.\n", url); 01733 return 0; 01734 } 01735 01736 if (LDAP_OPT_SUCCESS != ldap_set_option(ldapConn, LDAP_OPT_PROTOCOL_VERSION, &version)) { 01737 ast_log(LOG_WARNING, "Unable to set LDAP protocol version to %d, falling back to default.\n", version); 01738 } 01739 01740 if (!ast_strlen_zero(user)) { 01741 ast_debug(2, "bind to '%s' as user '%s'\n", url, user); 01742 cred.bv_val = (char *) pass; 01743 cred.bv_len = strlen(pass); 01744 bind_result = ldap_sasl_bind_s(ldapConn, user, LDAP_SASL_SIMPLE, &cred, NULL, NULL, NULL); 01745 } else { 01746 ast_debug(2, "bind %s anonymously\n", url); 01747 cred.bv_val = NULL; 01748 cred.bv_len = 0; 01749 bind_result = ldap_sasl_bind_s(ldapConn, NULL, LDAP_SASL_SIMPLE, &cred, NULL, NULL, NULL); 01750 } 01751 if (bind_result == LDAP_SUCCESS) { 01752 ast_debug(2, "Successfully connected to directory.\n"); 01753 connect_time = time(NULL); 01754 return 1; 01755 } else { 01756 ast_log(LOG_WARNING, "bind failed: %s\n", ldap_err2string(bind_result)); 01757 ldap_unbind_ext_s(ldapConn, NULL, NULL); 01758 ldapConn = NULL; 01759 return 0; 01760 } 01761 }
| static void ldap_table_config_add_attribute | ( | struct ldap_table_config * | table_config, | |
| const char * | attribute_name, | |||
| const char * | attribute_value | |||
| ) | [static] |
add attribute to table config - Should be locked before using it
Definition at line 182 of file res_config_ldap.c.
References ast_strlen_zero(), ast_variable_new(), ldap_table_config::attributes, ast_variable::next, ldap_table_config::table_name, and var.
Referenced by parse_config().
00184 { 00185 struct ast_variable *var; 00186 00187 if (ast_strlen_zero(attribute_name) || ast_strlen_zero(attribute_value)) { 00188 return; 00189 } 00190 00191 if (!(var = ast_variable_new(attribute_name, attribute_value, table_config->table_name))) { 00192 return; 00193 } 00194 00195 if (table_config->attributes) { 00196 var->next = table_config->attributes; 00197 } 00198 table_config->attributes = var; 00199 }
| static int load_module | ( | void | ) | [static] |
Definition at line 1544 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().
01545 { 01546 if (parse_config() < 0) { 01547 ast_log(LOG_ERROR, "Cannot load LDAP RealTime driver.\n"); 01548 return 0; 01549 } 01550 01551 ast_mutex_lock(&ldap_lock); 01552 01553 if (!ldap_reconnect()) { 01554 ast_log(LOG_WARNING, "Couldn't establish connection to LDAP directory. Check debug.\n"); 01555 } 01556 01557 ast_config_engine_register(&ldap_engine); 01558 ast_verb(1, "LDAP RealTime driver loaded.\n"); 01559 ast_cli_register_multiple(ldap_cli, ARRAY_LEN(ldap_cli)); 01560 01561 ast_mutex_unlock(&ldap_lock); 01562 01563 return 0; 01564 }
| static int parse_config | ( | void | ) | [static] |
parse the configuration file
< using the [config] context for Static RealTime
Definition at line 1616 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, static_table_config, table_config_for_table_name(), table_config_new(), table_configs_free(), ast_variable::value, and var.
01617 { 01618 struct ast_config *config; 01619 struct ast_flags config_flags = {0}; 01620 const char *s, *host; 01621 int port; 01622 char *category_name = NULL; 01623 01624 /* Make sure that global variables are reset */ 01625 url[0] = '\0'; 01626 user[0] = '\0'; 01627 pass[0] = '\0'; 01628 base_distinguished_name[0] = '\0'; 01629 version = 3; 01630 01631 config = ast_config_load(RES_CONFIG_LDAP_CONF, config_flags); 01632 if (config == CONFIG_STATUS_FILEMISSING || config == CONFIG_STATUS_FILEINVALID) { 01633 ast_log(LOG_ERROR, "Cannot load configuration file: %s\n", RES_CONFIG_LDAP_CONF); 01634 return -1; 01635 } 01636 01637 if (!(s = ast_variable_retrieve(config, "_general", "user"))) { 01638 ast_log(LOG_NOTICE, "No directory user found, anonymous binding as default.\n"); 01639 user[0] = '\0'; 01640 } else { 01641 ast_copy_string(user, s, sizeof(user)); 01642 } 01643 01644 if (!ast_strlen_zero(user)) { 01645 if (!(s = ast_variable_retrieve(config, "_general", "pass"))) { 01646 ast_log(LOG_WARNING, "No directory password found, using 'asterisk' as default.\n"); 01647 ast_copy_string(pass, "asterisk", sizeof(pass)); 01648 } else { 01649 ast_copy_string(pass, s, sizeof(pass)); 01650 } 01651 } 01652 01653 /* URL is preferred, use host and port if not found */ 01654 if ((s = ast_variable_retrieve(config, "_general", "url"))) { 01655 ast_copy_string(url, s, sizeof(url)); 01656 } else if ((host = ast_variable_retrieve(config, "_general", "host"))) { 01657 if (!(s = ast_variable_retrieve(config, "_general", "port")) || sscanf(s, "%5d", &port) != 1 || port > 65535) { 01658 ast_log(LOG_NOTICE, "No directory port found, using 389 as default.\n"); 01659 port = 389; 01660 } 01661 01662 snprintf(url, sizeof(url), "ldap://%s:%d", host, port); 01663 } else { 01664 ast_log(LOG_ERROR, "No directory URL or host found.\n"); 01665 ast_config_destroy(config); 01666 return -1; 01667 } 01668 01669 if (!(s = ast_variable_retrieve(config, "_general", "basedn"))) { 01670 ast_log(LOG_ERROR, "No LDAP base dn found, using '%s' as default.\n", RES_CONFIG_LDAP_DEFAULT_BASEDN); 01671 ast_copy_string(base_distinguished_name, RES_CONFIG_LDAP_DEFAULT_BASEDN, sizeof(base_distinguished_name)); 01672 } else 01673 ast_copy_string(base_distinguished_name, s, sizeof(base_distinguished_name)); 01674 01675 if (!(s = ast_variable_retrieve(config, "_general", "version")) && !(s = ast_variable_retrieve(config, "_general", "protocol"))) { 01676 ast_log(LOG_NOTICE, "No explicit LDAP version found, using 3 as default.\n"); 01677 } else if (sscanf(s, "%30d", &version) != 1 || version < 1 || version > 6) { 01678 ast_log(LOG_WARNING, "Invalid LDAP version '%s', using 3 as default.\n", s); 01679 version = 3; 01680 } 01681 01682 table_configs_free(); 01683 01684 while ((category_name = ast_category_browse(config, category_name))) { 01685 int is_general = (strcasecmp(category_name, "_general") == 0); 01686 int is_config = (strcasecmp(category_name, "config") == 0); /*!< using the [config] context for Static RealTime */ 01687 struct ast_variable *var = ast_variable_browse(config, category_name); 01688 01689 if (var) { 01690 struct ldap_table_config *table_config = 01691 table_config_for_table_name(category_name); 01692 if (!table_config) { 01693 table_config = table_config_new(category_name); 01694 AST_LIST_INSERT_HEAD(&table_configs, table_config, entry); 01695 if (is_general) 01696 base_table_config = table_config; 01697 if (is_config) 01698 static_table_config = table_config; 01699 } 01700 for (; var; var = var->next) { 01701 if (!strcasecmp(var->name, "additionalFilter")) { 01702 table_config->additional_filter = ast_strdup(var->value); 01703 } else { 01704 ldap_table_config_add_attribute(table_config, var->name, var->value); 01705 } 01706 } 01707 } 01708 } 01709 01710 ast_config_destroy(config); 01711 01712 return 1; 01713 }
| 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 925 of file res_config_ldap.c.
References free, ast_variable::next, realtime_ldap_base_ap(), and var.
00927 { 00928 struct ast_variable **vars = realtime_ldap_base_ap(NULL, basedn, table_name, ap); 00929 struct ast_variable *var = NULL; 00930 00931 if (vars) { 00932 struct ast_variable *last_var = NULL; 00933 struct ast_variable **p = vars; 00934 00935 /* Chain the vars array of lists into one list to return. */ 00936 while (*p) { 00937 if (last_var) { 00938 while (last_var->next) { 00939 last_var = last_var->next; 00940 } 00941 last_var->next = *p; 00942 } else { 00943 var = *p; 00944 last_var = var; 00945 } 00946 p++; 00947 } 00948 free(vars); 00949 } 00950 return var; 00951 }
| 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 908 of file res_config_ldap.c.
References realtime_ldap_base_ap().
Referenced by config_ldap().
00910 { 00911 struct ast_variable **vars = NULL; 00912 va_list ap; 00913 00914 va_start(ap, table_name); 00915 vars = realtime_ldap_base_ap(entries_count_ptr, basedn, table_name, ap); 00916 va_end(ap); 00917 00918 return vars; 00919 }
| 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_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_debug(1, "Failed to query directory. 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 directory. 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 /*! 00868 * \todo XXX The interactions with base_var and append_var may 00869 * cause a memory leak of base_var nodes. Also the append_var 00870 * list and base_var list may get cross linked. 00871 */ 00872 if (append_var) { 00873 base_var->next = append_var; 00874 } else { 00875 base_var->next = NULL; 00876 } 00877 append_var = base_var; 00878 base_var = next; 00879 } 00880 } 00881 } 00882 if (!tmp->next && append_var) { 00883 tmp->next = append_var; 00884 tmp = NULL; 00885 } else { 00886 tmp = tmp->next; 00887 } 00888 } 00889 p++; 00890 } 00891 } 00892 } 00893 00894 if (filter) { 00895 ast_free(filter); 00896 } 00897 00898 if (clean_basedn) { 00899 ast_free(clean_basedn); 00900 } 00901 00902 ast_mutex_unlock(&ldap_lock); 00903 00904 return vars; 00905 }
| 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 279 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().
00281 { 00282 BerElement *ber = NULL; 00283 struct ast_variable *var = NULL; 00284 struct ast_variable *prev = NULL; 00285 int is_delimited = 0; 00286 int i = 0; 00287 char *ldap_attribute_name; 00288 struct berval *value; 00289 int pos = 0; 00290 00291 ldap_attribute_name = ldap_first_attribute(ldapConn, ldap_entry, &ber); 00292 00293 while (ldap_attribute_name) { 00294 struct berval **values = NULL; 00295 const char *attribute_name = convert_attribute_name_from_ldap(table_config, ldap_attribute_name); 00296 int is_realmed_password_attribute = strcasecmp(attribute_name, "md5secret") == 0; 00297 00298 values = ldap_get_values_len(ldapConn, ldap_entry, ldap_attribute_name); /* these are freed at the end */ 00299 if (values) { 00300 struct berval **v; 00301 char *valptr; 00302 00303 for (v = values; *v; v++) { 00304 value = *v; 00305 valptr = value->bv_val; 00306 ast_debug(2, "LINE(%d) attribute_name: %s LDAP value: %s\n", __LINE__, attribute_name, valptr); 00307 if (is_realmed_password_attribute) { 00308 if (!strncasecmp(valptr, "{md5}", 5)) { 00309 valptr += 5; 00310 } 00311 ast_debug(2, "md5: %s\n", valptr); 00312 } 00313 if (valptr) { 00314 /* ok, so looping through all delimited values except the last one (not, last character is not delimited...) */ 00315 if (is_delimited) { 00316 i = 0; 00317 pos = 0; 00318 while (!ast_strlen_zero(valptr + i)) { 00319 if (valptr[i] == ';') { 00320 valptr[i] = '\0'; 00321 if (prev) { 00322 prev->next = ast_variable_new(attribute_name, &valptr[pos], table_config->table_name); 00323 if (prev->next) { 00324 prev = prev->next; 00325 } 00326 } else { 00327 prev = var = ast_variable_new(attribute_name, &valptr[pos], table_config->table_name); 00328 } 00329 pos = i + 1; 00330 } 00331 i++; 00332 } 00333 } 00334 /* for the last delimited value or if the value is not delimited: */ 00335 if (prev) { 00336 prev->next = ast_variable_new(attribute_name, &valptr[pos], table_config->table_name); 00337 if (prev->next) { 00338 prev = prev->next; 00339 } 00340 } else { 00341 prev = var = ast_variable_new(attribute_name, &valptr[pos], table_config->table_name); 00342 } 00343 } 00344 } 00345 ldap_value_free_len(values); 00346 } 00347 ldap_memfree(ldap_attribute_name); 00348 ldap_attribute_name = ldap_next_attribute(ldapConn, ldap_entry, ber); 00349 } 00350 ber_free(ber, 0); 00351 00352 return var; 00353 }
| static struct ast_variable** realtime_ldap_result_to_vars | ( | struct ldap_table_config * | table_config, | |
| LDAPMessage * | ldap_result_msg, | |||
| unsigned int * | entries_count_ptr | |||
| ) | [static, 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(), 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, value, var, and variable_named().
Referenced by ldap_loadentry(), and realtime_ldap_base_ap().
00363 { 00364 struct ast_variable **vars; 00365 int i = 0; 00366 int tot_count = 0; 00367 int entry_index = 0; 00368 LDAPMessage *ldap_entry = NULL; 00369 BerElement *ber = NULL; 00370 struct ast_variable *var = NULL; 00371 struct ast_variable *prev = NULL; 00372 int is_delimited = 0; 00373 char *delim_value = NULL; 00374 int delim_tot_count = 0; 00375 int delim_count = 0; 00376 00377 /* First find the total count */ 00378 ldap_entry = ldap_first_entry(ldapConn, ldap_result_msg); 00379 00380 for (tot_count = 0; ldap_entry; tot_count++) { 00381 struct ast_variable *tmp = realtime_ldap_entry_to_var(table_config, ldap_entry); 00382 tot_count += semicolon_count_var(tmp); 00383 ldap_entry = ldap_next_entry(ldapConn, ldap_entry); 00384 ast_variables_destroy(tmp); 00385 } 00386 00387 if (entries_count_ptr) { 00388 *entries_count_ptr = tot_count; 00389 } 00390 00391 /* Now that we have the total count we allocate space and create the variables 00392 * Remember that each element in vars is a linked list that points to realtime variable. 00393 * If the we are dealing with a static realtime variable we create a new element in the \a vars array for each delimited 00394 * value in \a variable_value; otherwise, we keep \a vars static and increase the length of the linked list of variables in the array element. 00395 * This memory must be freed outside of this function. */ 00396 vars = ast_calloc(sizeof(struct ast_variable *), tot_count + 1); 00397 00398 ldap_entry = ldap_first_entry(ldapConn, ldap_result_msg); 00399 00400 i = 0; 00401 00402 /* For each static realtime variable we may create several entries in the \a vars array if it's delimited */ 00403 for (entry_index = 0; ldap_entry; ) { 00404 int pos = 0; 00405 delim_value = NULL; 00406 delim_tot_count = 0; 00407 delim_count = 0; 00408 00409 do { /* while delim_count */ 00410 00411 /* Starting new static var */ 00412 char *ldap_attribute_name = ldap_first_attribute(ldapConn, ldap_entry, &ber); 00413 struct berval *value; 00414 while (ldap_attribute_name) { 00415 const char *attribute_name = convert_attribute_name_from_ldap(table_config, ldap_attribute_name); 00416 int is_realmed_password_attribute = strcasecmp(attribute_name, "md5secret") == 0; 00417 struct berval **values = NULL; 00418 00419 values = ldap_get_values_len(ldapConn, ldap_entry, ldap_attribute_name); 00420 if (values) { 00421 struct berval **v; 00422 char *valptr; 00423 00424 for (v = values; *v; v++) { 00425 value = *v; 00426 valptr = value->bv_val; 00427 if (is_realmed_password_attribute) { 00428 if (strncasecmp(valptr, "{md5}", 5) == 0) { 00429 valptr += 5; 00430 } 00431 ast_debug(2, "md5: %s\n", valptr); 00432 } 00433 if (valptr) { 00434 if (delim_value == NULL && !is_realmed_password_attribute 00435 && (static_table_config != table_config || strcmp(attribute_name, "variable_value") == 0)) { 00436 00437 delim_value = ast_strdup(valptr); 00438 00439 if ((delim_tot_count = semicolon_count_str(delim_value)) > 0) { 00440 ast_debug(4, "LINE(%d) is delimited %d times: %s\n", __LINE__, delim_tot_count, delim_value); 00441 is_delimited = 1; 00442 } 00443 } 00444 00445 if (is_delimited != 0 && !is_realmed_password_attribute 00446 && (static_table_config != table_config || strcmp(attribute_name, "variable_value") == 0) ) { 00447 /* for non-Static RealTime, first */ 00448 00449 for (i = pos; !ast_strlen_zero(valptr + i); i++) { 00450 ast_debug(4, "LINE(%d) DELIM pos: %d i: %d\n", __LINE__, pos, i); 00451 if (delim_value[i] == ';') { 00452 delim_value[i] = '\0'; 00453 00454 ast_debug(2, "LINE(%d) DELIM - attribute_name: %s value: %s pos: %d\n", __LINE__, attribute_name, &delim_value[pos], pos); 00455 00456 if (prev) { 00457 prev->next = ast_variable_new(attribute_name, &delim_value[pos], table_config->table_name); 00458 if (prev->next) { 00459 prev = prev->next; 00460 } 00461 } else { 00462 prev = var = ast_variable_new(attribute_name, &delim_value[pos], table_config->table_name); 00463 } 00464 pos = i + 1; 00465 00466 if (static_table_config == table_config) { 00467 break; 00468 } 00469 } 00470 } 00471 if (ast_strlen_zero(valptr + i)) { 00472 ast_debug(4, "LINE(%d) DELIM pos: %d i: %d delim_count: %d\n", __LINE__, pos, i, delim_count); 00473 /* Last delimited value */ 00474 ast_debug(4, "LINE(%d) DELIM - attribute_name: %s value: %s pos: %d\n", __LINE__, attribute_name, &delim_value[pos], pos); 00475 if (prev) { 00476 prev->next = ast_variable_new(attribute_name, &delim_value[pos], table_config->table_name); 00477 if (prev->next) { 00478 prev = prev->next; 00479 } 00480 } else { 00481 prev = var = ast_variable_new(attribute_name, &delim_value[pos], table_config->table_name); 00482 } 00483 /* Remembering to free memory */ 00484 is_delimited = 0; 00485 pos = 0; 00486 } 00487 free(delim_value); 00488 delim_value = NULL; 00489 00490 ast_debug(4, "LINE(%d) DELIM pos: %d i: %d\n", __LINE__, pos, i); 00491 } else { 00492 /* not delimited */ 00493 if (delim_value) { 00494 free(delim_value); 00495 delim_value = NULL; 00496 } 00497 ast_debug(2, "LINE(%d) attribute_name: %s value: %s\n", __LINE__, attribute_name, valptr); 00498 00499 if (prev) { 00500 prev->next = ast_variable_new(attribute_name, valptr, table_config->table_name); 00501 if (prev->next) { 00502 prev = prev->next; 00503 } 00504 } else { 00505 prev = var = ast_variable_new(attribute_name, valptr, table_config->table_name); 00506 } 00507 } 00508 } 00509 } /*!< for (v = values; *v; v++) */ 00510 ldap_value_free_len(values); 00511 }/*!< if (values) */ 00512 ldap_memfree(ldap_attribute_name); 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 1763 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.
01764 { 01765 char status[256], credentials[100] = ""; 01766 int ctimesec = time(NULL) - connect_time; 01767 01768 switch (cmd) { 01769 case CLI_INIT: 01770 e->command = "realtime show ldap status"; 01771 e->usage = 01772 "Usage: realtime show ldap status\n" 01773 " Shows connection information for the LDAP RealTime driver\n"; 01774 return NULL; 01775 case CLI_GENERATE: 01776 return NULL; 01777 } 01778 01779 if (!ldapConn) 01780 return CLI_FAILURE; 01781 01782 if (!ast_strlen_zero(url)) 01783 snprintf(status, sizeof(status), "Connected to '%s', baseDN %s", url, base_distinguished_name); 01784 01785 if (!ast_strlen_zero(user)) 01786 snprintf(credentials, sizeof(credentials), " with username %s", user); 01787 01788 if (ctimesec > 31536000) { 01789 ast_cli(a->fd, "%s%s for %d years, %d days, %d hours, %d minutes, %d seconds.\n", 01790 status, credentials, ctimesec / 31536000, 01791 (ctimesec % 31536000) / 86400, (ctimesec % 86400) / 3600, 01792 (ctimesec % 3600) / 60, ctimesec % 60); 01793 } else if (ctimesec > 86400) { 01794 ast_cli(a->fd, "%s%s for %d days, %d hours, %d minutes, %d seconds.\n", 01795 status, credentials, ctimesec / 86400, (ctimesec % 86400) / 3600, 01796 (ctimesec % 3600) / 60, ctimesec % 60); 01797 } else if (ctimesec > 3600) { 01798 ast_cli(a->fd, "%s%s for %d hours, %d minutes, %d seconds.\n", 01799 status, credentials, ctimesec / 3600, (ctimesec % 3600) / 60, 01800 ctimesec % 60); 01801 } else if (ctimesec > 60) { 01802 ast_cli(a->fd, "%s%s for %d minutes, %d seconds.\n", status, credentials, 01803 ctimesec / 60, ctimesec % 60); 01804 } else { 01805 ast_cli(a->fd, "%s%s for %d seconds.\n", status, credentials, ctimesec); 01806 } 01807 01808 return CLI_SUCCESS; 01809 }
| 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 960 of file res_config_ldap.c.
References ast_category_append(), ast_category_new(), ast_category_rename(), ast_config_new(), ast_log(), ast_strdupa, ast_variable_append(), free, LOG_ERROR, LOG_WARNING, ast_variable::name, ast_variable::next, ldap_table_config::next, realtime_ldap_base_ap(), ast_variable::value, and var.
00962 { 00963 char *op; 00964 const char *initfield = NULL; 00965 const char *newparam, *newval; 00966 struct ast_variable **vars = 00967 realtime_ldap_base_ap(NULL, basedn, table_name, ap); 00968 struct ast_config *cfg = NULL; 00969 00970 newparam = va_arg(ap, const char *); 00971 newval = va_arg(ap, const char *); 00972 if (!newparam || !newval) { 00973 ast_log(LOG_WARNING, "realtime retrieval requires at least 1 parameter and 1 value to search on.\n"); 00974 return NULL; 00975 } 00976 initfield = ast_strdupa(newparam); 00977 if ((op = strchr(initfield, ' '))) { 00978 *op = '\0'; 00979 } 00980 00981 if (vars) { 00982 cfg = ast_config_new(); 00983 if (!cfg) { 00984 ast_log(LOG_ERROR, "Unable to create a config!\n"); 00985 } else { 00986 struct ast_variable **p = vars; 00987 00988 while (*p) { 00989 struct ast_category *cat = NULL; 00990 cat = ast_category_new("", table_name, -1); 00991 if (!cat) { 00992 ast_log(LOG_ERROR, "Unable to create a new category!\n"); 00993 break; 00994 } else { 00995 struct ast_variable *var = *p; 00996 while (var) { 00997 struct ast_variable *next = var->next; 00998 if (initfield && !strcmp(initfield, var->name)) { 00999 ast_category_rename(cat, var->value); 01000 } 01001 var->next = NULL; 01002 ast_variable_append(cat, var); 01003 var = next; 01004 } 01005 } 01006 ast_category_append(cfg, cat); 01007 p++; 01008 } 01009 } 01010 free(vars); 01011 } 01012 return cfg; 01013 01014 }
| static int reload | ( | void | ) | [static] |
Definition at line 1587 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().
01588 { 01589 /* Aquire control before doing anything to the module itself. */ 01590 ast_mutex_lock(&ldap_lock); 01591 01592 if (ldapConn) { 01593 ldap_unbind_ext_s(ldapConn, NULL, NULL); 01594 ldapConn = NULL; 01595 } 01596 01597 if (parse_config() < 0) { 01598 ast_log(LOG_NOTICE, "Cannot reload LDAP RealTime driver.\n"); 01599 ast_mutex_unlock(&ldap_lock); 01600 return 0; 01601 } 01602 01603 if (!ldap_reconnect()) { 01604 ast_log(LOG_WARNING, "Couldn't establish connection to your directory server. Check debug.\n"); 01605 } 01606 01607 ast_verb(2, "LDAP RealTime driver reloaded.\n"); 01608 01609 /* Done reloading. Release lock so others can now use driver. */ 01610 ast_mutex_unlock(&ldap_lock); 01611 01612 return 0; 01613 }
| 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 153 of file res_config_ldap.c.
Referenced by realtime_ldap_result_to_vars(), and semicolon_count_var().
00154 { 00155 int count = 0; 00156 00157 for (; *somestr; somestr++) { 00158 if (*somestr == ';') 00159 count++; 00160 } 00161 00162 return count; 00163 }
| static int semicolon_count_var | ( | struct ast_variable * | var | ) | [static] |
Definition at line 168 of file res_config_ldap.c.
References ast_debug, semicolon_count_str(), ast_variable::value, and variable_named().
Referenced by realtime_ldap_result_to_vars().
00169 { 00170 struct ast_variable *var_value = variable_named(var, "variable_value"); 00171 00172 if (!var_value) { 00173 return 0; 00174 } 00175 00176 ast_debug(2, "LINE(%d) semicolon_count_var: %s\n", __LINE__, var_value->value); 00177 00178 return semicolon_count_str(var_value->value); 00179 }
| static char* substituted | ( | struct ast_channel * | channel, | |
| const char * | string | |||
| ) | [static] |
Definition at line 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 125 of file res_config_ldap.c.
References AST_LIST_TRAVERSE, ldap_table_config::entry, and ldap_table_config::table_name.
Referenced by parse_config(), realtime_ldap_base_ap(), update2_ldap(), and update_ldap().
00126 { 00127 struct ldap_table_config *c = NULL; 00128 00129 AST_LIST_TRAVERSE(&table_configs, c, entry) { 00130 if (!strcmp(c->table_name, table_name)) 00131 break; 00132 } 00133 00134 return c; 00135 }
| static struct ldap_table_config* table_config_new | ( | const char * | table_name | ) | [static, read] |
Create a new table_config.
Definition at line 106 of file res_config_ldap.c.
References ast_calloc, ast_strdup, free, and ldap_table_config::table_name.
Referenced by parse_config().
00107 { 00108 struct ldap_table_config *p; 00109 00110 if (!(p = ast_calloc(1, sizeof(*p)))) 00111 return NULL; 00112 00113 if (table_name) { 00114 if (!(p->table_name = ast_strdup(table_name))) { 00115 free(p); 00116 return NULL; 00117 } 00118 } 00119 00120 return p; 00121 }
| static void table_configs_free | ( | void | ) | [static] |
Free table_config.
Definition at line 203 of file res_config_ldap.c.
References ldap_table_config::additional_filter, ast_free, AST_LIST_REMOVE_HEAD, ast_variables_destroy(), ldap_table_config::attributes, base_table_config, ldap_table_config::entry, free, static_table_config, and ldap_table_config::table_name.
Referenced by parse_config(), and unload_module().
00204 { 00205 struct ldap_table_config *c; 00206 00207 while ((c = AST_LIST_REMOVE_HEAD(&table_configs, entry))) { 00208 if (c->table_name) { 00209 ast_free(c->table_name); 00210 } 00211 if (c->additional_filter) { 00212 ast_free(c->additional_filter); 00213 } 00214 if (c->attributes) { 00215 ast_variables_destroy(c->attributes); 00216 } 00217 free(c); 00218 } 00219 00220 base_table_config = NULL; 00221 static_table_config = NULL; 00222 }
| static int unload_module | ( | void | ) | [static] |
Definition at line 1566 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().
01567 { 01568 /* Aquire control before doing anything to the module itself. */ 01569 ast_mutex_lock(&ldap_lock); 01570 01571 table_configs_free(); 01572 01573 if (ldapConn) { 01574 ldap_unbind_ext_s(ldapConn, NULL, NULL); 01575 ldapConn = NULL; 01576 } 01577 ast_cli_unregister_multiple(ldap_cli, ARRAY_LEN(ldap_cli)); 01578 ast_config_engine_deregister(&ldap_engine); 01579 ast_verb(1, "LDAP RealTime driver unloaded.\n"); 01580 01581 /* Unlock so something else can destroy the lock. */ 01582 ast_mutex_unlock(&ldap_lock); 01583 01584 return 0; 01585 }
| static int update2_ldap | ( | const char * | basedn, | |
| const char * | table_name, | |||
| va_list | ap | |||
| ) | [static] |
Definition at line 1349 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().
01350 { 01351 int error = 0; 01352 LDAPMessage *ldap_entry = NULL; 01353 LDAPMod **ldap_mods; 01354 const char *newparam = NULL; 01355 const char *newval = NULL; 01356 char *dn; 01357 int num_entries = 0; 01358 int i = 0; 01359 int mods_size = 0; 01360 int mod_exists = 0; 01361 struct ldap_table_config *table_config = NULL; 01362 char *clean_basedn = NULL; 01363 struct ast_str *filter = NULL; 01364 int tries = 0; 01365 int result = 0; 01366 LDAPMessage *ldap_result_msg = NULL; 01367 01368 if (!table_name) { 01369 ast_log(LOG_ERROR, "No table_name specified.\n"); 01370 return -1; 01371 } 01372 01373 if (!(filter = ast_str_create(80))) { 01374 return -1; 01375 } 01376 01377 ast_mutex_lock(&ldap_lock); 01378 01379 /* We now have our complete statement; Lets connect to the server and execute it. */ 01380 if (!ldap_reconnect()) { 01381 ast_mutex_unlock(&ldap_lock); 01382 ast_free(filter); 01383 return -1; 01384 } 01385 01386 table_config = table_config_for_table_name(table_name); 01387 if (!table_config) { 01388 ast_log(LOG_ERROR, "No table named '%s'.\n", table_name); 01389 ast_mutex_unlock(&ldap_lock); 01390 ast_free(filter); 01391 return -1; 01392 } 01393 01394 clean_basedn = cleaned_basedn(NULL, basedn); 01395 01396 /* Create the filter with the table additional filter and the parameter/value pairs we were given */ 01397 ast_str_append(&filter, 0, "(&"); 01398 if (table_config && table_config->additional_filter) { 01399 ast_str_append(&filter, 0, "%s", table_config->additional_filter); 01400 } 01401 if (table_config != base_table_config && base_table_config 01402 && base_table_config->additional_filter) { 01403 ast_str_append(&filter, 0, "%s", base_table_config->additional_filter); 01404 } 01405 01406 /* Get multiple lookup keyfields and values */ 01407 while ((newparam = va_arg(ap, const char *))) { 01408 newval = va_arg(ap, const char *); 01409 append_var_and_value_to_filter(&filter, table_config, newparam, newval); 01410 } 01411 ast_str_append(&filter, 0, ")"); 01412 01413 /* Create the modification array with the parameter/value pairs we were given, 01414 * if there are several parameters with the same name, we collect them into 01415 * one parameter/value pair and delimit them with a semicolon */ 01416 newparam = va_arg(ap, const char *); 01417 newparam = convert_attribute_name_to_ldap(table_config, newparam); 01418 newval = va_arg(ap, const char *); 01419 if (!newparam || !newval) { 01420 ast_log(LOG_WARNING, "LINE(%d): need at least one parameter to modify.\n", __LINE__); 01421 ast_free(filter); 01422 ast_free(clean_basedn); 01423 return -1; 01424 } 01425 01426 mods_size = 2; /* one for the first param/value pair and one for the the terminating NULL */ 01427 ldap_mods = ast_calloc(sizeof(LDAPMod *), mods_size); 01428 ldap_mods[0] = ast_calloc(1, sizeof(LDAPMod)); 01429 01430 ldap_mods[0]->mod_op = LDAP_MOD_REPLACE; 01431 ldap_mods[0]->mod_type = ast_calloc(sizeof(char), strlen(newparam) + 1); 01432 strcpy(ldap_mods[0]->mod_type, newparam); 01433 01434 ldap_mods[0]->mod_values = ast_calloc(sizeof(char), 2); 01435 ldap_mods[0]->mod_values[0] = ast_calloc(sizeof(char), strlen(newval) + 1); 01436 strcpy(ldap_mods[0]->mod_values[0], newval); 01437 01438 while ((newparam = va_arg(ap, const char *))) { 01439 newparam = convert_attribute_name_to_ldap(table_config, newparam); 01440 newval = va_arg(ap, const char *); 01441 mod_exists = 0; 01442 01443 for (i = 0; i < mods_size - 1; i++) { 01444 if (ldap_mods[i]&& !strcmp(ldap_mods[i]->mod_type, newparam)) { 01445 /* We have the parameter allready, adding the value as a semicolon delimited value */ 01446 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)); 01447 strcat(ldap_mods[i]->mod_values[0], ";"); 01448 strcat(ldap_mods[i]->mod_values[0], newval); 01449 mod_exists = 1; 01450 break; 01451 } 01452 } 01453 01454 /* create new mod */ 01455 if (!mod_exists) { 01456 mods_size++; 01457 ldap_mods = ast_realloc(ldap_mods, sizeof(LDAPMod *) * mods_size); 01458 ldap_mods[mods_size - 1] = NULL; 01459 ldap_mods[mods_size - 2] = ast_calloc(1, sizeof(LDAPMod)); 01460 01461 ldap_mods[mods_size - 2]->mod_op = LDAP_MOD_REPLACE; 01462 01463 ldap_mods[mods_size - 2]->mod_type = ast_calloc(sizeof(char), strlen(newparam) + 1); 01464 strcpy(ldap_mods[mods_size - 2]->mod_type, newparam); 01465 01466 ldap_mods[mods_size - 2]->mod_values = ast_calloc(sizeof(char *), 2); 01467 ldap_mods[mods_size - 2]->mod_values[0] = ast_calloc(sizeof(char), strlen(newval) + 1); 01468 strcpy(ldap_mods[mods_size - 2]->mod_values[0], newval); 01469 } 01470 } 01471 /* freeing ldap_mods further down */ 01472 01473 do { 01474 /* freeing ldap_result further down */ 01475 result = ldap_search_ext_s(ldapConn, clean_basedn, 01476 LDAP_SCOPE_SUBTREE, ast_str_buffer(filter), NULL, 0, NULL, NULL, NULL, LDAP_NO_LIMIT, 01477 &ldap_result_msg); 01478 if (result != LDAP_SUCCESS && is_ldap_connect_error(result)) { 01479 ast_log(LOG_WARNING, "Failed to query directory. Try %d/3\n", tries + 1); 01480 tries++; 01481 if (tries < 3) { 01482 usleep(500000L * tries); 01483 if (ldapConn) { 01484 ldap_unbind_ext_s(ldapConn, NULL, NULL); 01485 ldapConn = NULL; 01486 } 01487 if (!ldap_reconnect()) { 01488 break; 01489 } 01490 } 01491 } 01492 } while (result != LDAP_SUCCESS && tries < 3 && is_ldap_connect_error(result)); 01493 01494 if (result != LDAP_SUCCESS) { 01495 ast_log(LOG_WARNING, "Failed to query directory. Error: %s.\n", ldap_err2string(result)); 01496 ast_log(LOG_WARNING, "Query: %s\n", ast_str_buffer(filter)); 01497 01498 ast_mutex_unlock(&ldap_lock); 01499 ast_free(filter); 01500 ast_free(clean_basedn); 01501 ldap_msgfree(ldap_result_msg); 01502 ldap_mods_free(ldap_mods, 0); 01503 return -1; 01504 } 01505 /* Ready to update */ 01506 if ((num_entries = ldap_count_entries(ldapConn, ldap_result_msg)) > 0) { 01507 for (i = 0; option_debug > 2 && i < mods_size - 1; i++) { 01508 ast_debug(3, "LINE(%d) %s=%s \n", __LINE__, ldap_mods[i]->mod_type, ldap_mods[i]->mod_values[0]); 01509 } 01510 01511 ldap_entry = ldap_first_entry(ldapConn, ldap_result_msg); 01512 01513 for (i = 0; ldap_entry; i++) { 01514 dn = ldap_get_dn(ldapConn, ldap_entry); 01515 if ((error = ldap_modify_ext_s(ldapConn, dn, ldap_mods, NULL, NULL)) != LDAP_SUCCESS) { 01516 ast_log(LOG_ERROR, "Couldn't modify dn:%s because %s", dn, ldap_err2string(error)); 01517 } 01518 ldap_memfree(dn); 01519 ldap_entry = ldap_next_entry(ldapConn, ldap_entry); 01520 } 01521 } 01522 01523 ast_mutex_unlock(&ldap_lock); 01524 if (filter) { 01525 ast_free(filter); 01526 } 01527 if (clean_basedn) { 01528 ast_free(clean_basedn); 01529 } 01530 ldap_msgfree(ldap_result_msg); 01531 ldap_mods_free(ldap_mods, 0); 01532 return num_entries; 01533 }
| static int update_ldap | ( | const char * | basedn, | |
| const char * | table_name, | |||
| const char * | attribute, | |||
| const char * | lookup, | |||
| va_list | ap | |||
| ) | [static] |
Definition at line 1165 of file res_config_ldap.c.
References ldap_table_config::additional_filter, append_var_and_value_to_filter(), ast_calloc, ast_debug, ast_free, ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_realloc, ast_str_append(), ast_str_buffer(), ast_str_create(), ast_strdup, base_table_config, cleaned_basedn(), convert_attribute_name_to_ldap(), filter(), free, is_ldap_connect_error(), ldap_lock, ldap_reconnect(), LOG_ERROR, LOG_WARNING, option_debug, and table_config_for_table_name().
01167 { 01168 int error = 0; 01169 LDAPMessage *ldap_entry = NULL; 01170 LDAPMod **ldap_mods; 01171 const char *newparam = NULL; 01172 const char *newval = NULL; 01173 char *dn; 01174 int num_entries = 0; 01175 int i = 0; 01176 int mods_size = 0; 01177 int mod_exists = 0; 01178 struct ldap_table_config *table_config = NULL; 01179 char *clean_basedn = NULL; 01180 struct ast_str *filter = NULL; 01181 int tries = 0; 01182 int result = 0; 01183 LDAPMessage *ldap_result_msg = NULL; 01184 01185 if (!table_name) { 01186 ast_log(LOG_ERROR, "No table_name specified.\n"); 01187 return -1; 01188 } 01189 01190 if (!(filter = ast_str_create(80))) { 01191 return -1; 01192 } 01193 01194 if (!attribute || !lookup) { 01195 ast_log(LOG_WARNING, "LINE(%d): search parameters are empty.\n", __LINE__); 01196 return -1; 01197 } 01198 ast_mutex_lock(&ldap_lock); 01199 01200 /* We now have our complete statement; Lets connect to the server and execute it. */ 01201 if (!ldap_reconnect()) { 01202 ast_mutex_unlock(&ldap_lock); 01203 return -1; 01204 } 01205 01206 table_config = table_config_for_table_name(table_name); 01207 if (!table_config) { 01208 ast_log(LOG_ERROR, "No table named '%s'.\n", table_name); 01209 ast_mutex_unlock(&ldap_lock); 01210 return -1; 01211 } 01212 01213 clean_basedn = cleaned_basedn(NULL, basedn); 01214 01215 /* Create the filter with the table additional filter and the parameter/value pairs we were given */ 01216 ast_str_append(&filter, 0, "(&"); 01217 if (table_config && table_config->additional_filter) { 01218 ast_str_append(&filter, 0, "%s", table_config->additional_filter); 01219 } 01220 if (table_config != base_table_config && base_table_config && base_table_config->additional_filter) { 01221 ast_str_append(&filter, 0, "%s", base_table_config->additional_filter); 01222 } 01223 append_var_and_value_to_filter(&filter, table_config, attribute, lookup); 01224 ast_str_append(&filter, 0, ")"); 01225 01226 /* Create the modification array with the parameter/value pairs we were given, 01227 * if there are several parameters with the same name, we collect them into 01228 * one parameter/value pair and delimit them with a semicolon */ 01229 newparam = va_arg(ap, const char *); 01230 newparam = convert_attribute_name_to_ldap(table_config, newparam); 01231 newval = va_arg(ap, const char *); 01232 if (!newparam || !newval) { 01233 ast_log(LOG_WARNING, "LINE(%d): need at least one parameter to modify.\n", __LINE__); 01234 return -1; 01235 } 01236 01237 mods_size = 2; /* one for the first param/value pair and one for the the terminating NULL */ 01238 ldap_mods = ast_calloc(sizeof(LDAPMod *), mods_size); 01239 ldap_mods[0] = ast_calloc(1, sizeof(LDAPMod)); 01240 01241 ldap_mods[0]->mod_op = LDAP_MOD_REPLACE; 01242 ldap_mods[0]->mod_type = ast_strdup(newparam); 01243 01244 ldap_mods[0]->mod_values = ast_calloc(sizeof(char *), 2); 01245 ldap_mods[0]->mod_values[0] = ast_strdup(newval); 01246 01247 while ((newparam = va_arg(ap, const char *))) { 01248 newparam = convert_attribute_name_to_ldap(table_config, newparam); 01249 newval = va_arg(ap, const char *); 01250 mod_exists = 0; 01251 01252 for (i = 0; i < mods_size - 1; i++) { 01253 if (ldap_mods[i]&& !strcmp(ldap_mods[i]->mod_type, newparam)) { 01254 /* We have the parameter allready, adding the value as a semicolon delimited value */ 01255 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)); 01256 strcat(ldap_mods[i]->mod_values[0], ";"); 01257 strcat(ldap_mods[i]->mod_values[0], newval); 01258 mod_exists = 1; 01259 break; 01260 } 01261 } 01262 01263 /* create new mod */ 01264 if (!mod_exists) { 01265 mods_size++; 01266 ldap_mods = ast_realloc(ldap_mods, sizeof(LDAPMod *) * mods_size); 01267 ldap_mods[mods_size - 1] = NULL; 01268 01269 ldap_mods[mods_size - 2] = ast_calloc(1, sizeof(LDAPMod)); 01270 01271 ldap_mods[mods_size - 2]->mod_type = ast_calloc(sizeof(char), strlen(newparam) + 1); 01272 strcpy(ldap_mods[mods_size - 2]->mod_type, newparam); 01273 01274 if (strlen(newval) == 0) { 01275 ldap_mods[mods_size - 2]->mod_op = LDAP_MOD_DELETE; 01276 } else { 01277 ldap_mods[mods_size - 2]->mod_op = LDAP_MOD_REPLACE; 01278 01279 ldap_mods[mods_size - 2]->mod_values = ast_calloc(sizeof(char *), 2); 01280 ldap_mods[mods_size - 2]->mod_values[0] = ast_calloc(sizeof(char), strlen(newval) + 1); 01281 strcpy(ldap_mods[mods_size - 2]->mod_values[0], newval); 01282 } 01283 } 01284 } 01285 /* freeing ldap_mods further down */ 01286 01287 do { 01288 /* freeing ldap_result further down */ 01289 result = ldap_search_ext_s(ldapConn, clean_basedn, 01290 LDAP_SCOPE_SUBTREE, ast_str_buffer(filter), NULL, 0, NULL, NULL, NULL, LDAP_NO_LIMIT, 01291 &ldap_result_msg); 01292 if (result != LDAP_SUCCESS && is_ldap_connect_error(result)) { 01293 ast_log(LOG_WARNING, "Failed to query directory. Try %d/3\n", tries + 1); 01294 tries++; 01295 if (tries < 3) { 01296 usleep(500000L * tries); 01297 if (ldapConn) { 01298 ldap_unbind_ext_s(ldapConn, NULL, NULL); 01299 ldapConn = NULL; 01300 } 01301 if (!ldap_reconnect()) 01302 break; 01303 } 01304 } 01305 } while (result != LDAP_SUCCESS && tries < 3 && is_ldap_connect_error(result)); 01306 01307 if (result != LDAP_SUCCESS) { 01308 ast_log(LOG_WARNING, "Failed to query directory. Error: %s.\n", ldap_err2string(result)); 01309 ast_log(LOG_WARNING, "Query: %s\n", ast_str_buffer(filter)); 01310 01311 ast_mutex_unlock(&ldap_lock); 01312 free(filter); 01313 free(clean_basedn); 01314 ldap_msgfree(ldap_result_msg); 01315 ldap_mods_free(ldap_mods, 0); 01316 return -1; 01317 } 01318 /* Ready to update */ 01319 if ((num_entries = ldap_count_entries(ldapConn, ldap_result_msg)) > 0) { 01320 ast_debug(3, "LINE(%d) Modifying %s=%s hits: %d\n", __LINE__, attribute, lookup, num_entries); 01321 for (i = 0; option_debug > 2 && i < mods_size - 1; i++) { 01322 if (ldap_mods[i]->mod_op != LDAP_MOD_DELETE) { 01323 ast_debug(3, "LINE(%d) %s=%s \n", __LINE__, ldap_mods[i]->mod_type, ldap_mods[i]->mod_values[0]); 01324 } else { 01325 ast_debug(3, "LINE(%d) deleting %s \n", __LINE__, ldap_mods[i]->mod_type); 01326 } 01327 } 01328 ldap_entry = ldap_first_entry(ldapConn, ldap_result_msg); 01329 01330 for (i = 0; ldap_entry; i++) { 01331 dn = ldap_get_dn(ldapConn, ldap_entry); 01332 if ((error = ldap_modify_ext_s(ldapConn, dn, ldap_mods, NULL, NULL)) != LDAP_SUCCESS) { 01333 ast_log(LOG_ERROR, "Couldn't modify '%s'='%s', dn:%s because %s\n", 01334 attribute, lookup, dn, ldap_err2string(error)); 01335 } 01336 ldap_memfree(dn); 01337 ldap_entry = ldap_next_entry(ldapConn, ldap_entry); 01338 } 01339 } 01340 01341 ast_mutex_unlock(&ldap_lock); 01342 ast_free(filter); 01343 ast_free(clean_basedn); 01344 ldap_msgfree(ldap_result_msg); 01345 ldap_mods_free(ldap_mods, 0); 01346 return num_entries; 01347 }
| static struct ast_variable* variable_named | ( | struct ast_variable * | var, | |
| const char * | name | |||
| ) | [static, read] |
Find variable by name.
Definition at line 138 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().
00139 { 00140 for (; var; var = var->next) { 00141 if (!strcasecmp(name, var->name)) 00142 break; 00143 } 00144 00145 return var; 00146 }
struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "LDAP realtime interface" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_REALTIME_DRIVER, } [static] |
Definition at line 1816 of file res_config_ldap.c.
struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 1816 of file res_config_ldap.c.
char base_distinguished_name[512] [static] |
Definition at line 70 of file res_config_ldap.c.
struct ldap_table_config* base_table_config [static] |
Definition at line 98 of file res_config_ldap.c.
Referenced by convert_attribute_name_from_ldap(), convert_attribute_name_to_ldap(), parse_config(), realtime_ldap_base_ap(), table_configs_free(), update2_ldap(), and update_ldap().
time_t connect_time [static] |
Definition at line 72 of file res_config_ldap.c.
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 101 of file res_config_ldap.c.
Referenced by load_module(), and unload_module().
struct ast_config_engine ldap_engine [static] |
Definition at line 1535 of file res_config_ldap.c.
Referenced by load_module(), and unload_module().
ast_mutex_t ldap_lock = { PTHREAD_MUTEX_INITIALIZER , NULL, 1 } [static] |
Definition at line 64 of file res_config_ldap.c.
Referenced by ldap_loadentry(), load_module(), realtime_ldap_base_ap(), reload(), unload_module(), update2_ldap(), and update_ldap().
LDAP* ldapConn [static] |
Definition at line 66 of file res_config_ldap.c.
char pass[512] [static] |
Definition at line 69 of file res_config_ldap.c.
Referenced by __ast_dsp_call_progress(), AST_TEST_DEFINE(), build_transactions(), gtalk_create_candidates(), jingle_create_candidates(), and login_exec().
struct ldap_table_config* static_table_config [static] |
Definition at line 99 of file res_config_ldap.c.
Referenced by parse_config(), realtime_ldap_result_to_vars(), and table_configs_free().
char url[512] [static] |
Definition at line 67 of file res_config_ldap.c.
Referenced by acf_curl_helper(), caldav_load_calendar(), dial_exec_full(), ewscal_load_calendar(), exchangecal_load_calendar(), ical_load_calendar(), queue_exec(), reqprep(), respprep(), sendurl_exec(), and sip_sendhtml().
char user[512] [static] |
Definition at line 68 of file res_config_ldap.c.
int version [static] |
Definition at line 71 of file res_config_ldap.c.
1.5.6