00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #include <stdio.h>
00034 #include <string.h>
00035 #include <sys/time.h>
00036
00037 #include "../../ut.h"
00038 #include "../../parser/hf.h"
00039 #include "../../sr_module.h"
00040 #include "../../pvar.h"
00041 #include "../../mem/mem.h"
00042
00043 #include "ld_session.h"
00044 #include "ldap_exp_fn.h"
00045 #include "api.h"
00046 #include "ldap_connect.h"
00047 #include "ldap_api_fn.h"
00048 #include "iniparser.h"
00049
00050 MODULE_VERSION
00051
00052
00053
00054
00055 static int mod_init(void);
00056 static void destroy(void);
00057 static int child_init(int rank);
00058
00059
00060
00061
00062 static int ldap_search_fixup(void** param, int param_no);
00063 static int ldap_result_fixup(void** param, int param_no);
00064 static int ldap_filter_url_encode_fixup(void** param, int param_no);
00065 static int ldap_result_check_fixup(void** param, int param_no);
00066
00067
00068
00069
00070
00071 static int w_ldap_search(struct sip_msg* msg, char* ldap_url, char* param);
00072 static int w_ldap_result1(struct sip_msg* msg, char* src, char* param);
00073 static int w_ldap_result2(struct sip_msg* msg, char* src, char* subst);
00074 static int w_ldap_result_next(struct sip_msg* msg, char* foo, char *bar);
00075 static int w_ldap_filter_url_encode(struct sip_msg* msg,
00076 char* filter_component, char* dst_avp_name);
00077 static int w_ldap_result_check_1(struct sip_msg* msg,
00078 char* attr_name_check_str, char* param);
00079 static int w_ldap_result_check_2(struct sip_msg* msg,
00080 char* attr_name_check_str, char* attr_val_re);
00081
00082
00083
00084
00085
00086 #define DEF_LDAP_CONFIG "/usr/local/etc/kamailio/ldap.cfg"
00087
00088
00089
00090
00091 str ldap_config = str_init(DEF_LDAP_CONFIG);
00092 static dictionary* config_vals = NULL;
00093
00094
00095
00096
00097 static cmd_export_t cmds[] = {
00098 {"ldap_search", (cmd_function)w_ldap_search, 1,
00099 ldap_search_fixup, 0,
00100 REQUEST_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE|ONREPLY_ROUTE|LOCAL_ROUTE},
00101 {"ldap_result", (cmd_function)w_ldap_result1, 1,
00102 ldap_result_fixup, 0,
00103 REQUEST_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE|ONREPLY_ROUTE|LOCAL_ROUTE},
00104 {"ldap_result", (cmd_function)w_ldap_result2, 2,
00105 ldap_result_fixup, 0,
00106 REQUEST_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE|ONREPLY_ROUTE|LOCAL_ROUTE},
00107 {"ldap_result_next", (cmd_function)w_ldap_result_next, 0,
00108 0, 0,
00109 REQUEST_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE|ONREPLY_ROUTE|LOCAL_ROUTE},
00110 {"ldap_result_check", (cmd_function)w_ldap_result_check_1, 1,
00111 ldap_result_check_fixup, 0,
00112 REQUEST_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE|ONREPLY_ROUTE|LOCAL_ROUTE},
00113 {"ldap_result_check", (cmd_function)w_ldap_result_check_2, 2,
00114 ldap_result_check_fixup, 0,
00115 REQUEST_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE|ONREPLY_ROUTE|LOCAL_ROUTE},
00116 {"ldap_filter_url_encode", (cmd_function)w_ldap_filter_url_encode, 2,
00117 ldap_filter_url_encode_fixup, 0,
00118 REQUEST_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE|ONREPLY_ROUTE|LOCAL_ROUTE},
00119 {"load_ldap", (cmd_function)load_ldap, 0,
00120 0, 0,
00121 0},
00122 {0, 0, 0, 0, 0, 0}
00123 };
00124
00125
00126
00127
00128
00129 static param_export_t params[] = {
00130
00131 {"config_file", STR_PARAM, &ldap_config},
00132 {0, 0, 0}
00133 };
00134
00135
00136
00137
00138
00139 struct module_exports exports = {
00140 "ldap",
00141 DEFAULT_DLFLAGS,
00142 cmds,
00143 params,
00144 0,
00145 0,
00146 0,
00147 0,
00148 mod_init,
00149 0,
00150 destroy,
00151 child_init
00152 };
00153
00154
00155 static int child_init(int rank)
00156 {
00157 int i = 0, ld_count = 0;
00158 char* ld_name;
00159
00160
00161 if (rank < 1) {
00162 return 0;
00163 }
00164
00165
00166
00167
00168 ld_count = iniparser_getnsec(config_vals);
00169 for (i = 0; i < ld_count; i++)
00170 {
00171 ld_name = iniparser_getsecname(config_vals, i);
00172 if (add_ld_session(ld_name,
00173 NULL,
00174 config_vals)
00175 != 0)
00176 {
00177 LM_ERR("[%s]: add_ld_session failed\n", ld_name);
00178 return -1;
00179 }
00180
00181 if (ldap_connect(ld_name) != 0)
00182 {
00183 LM_ERR("[%s]: failed to connect to LDAP host(s)\n", ld_name);
00184 ldap_disconnect(ld_name);
00185 return -1;
00186 }
00187
00188 }
00189
00190 return 0;
00191 }
00192
00193
00194 static int mod_init(void)
00195 {
00196 int ld_count = 0, i = 0;
00197 char* section_name;
00198 char* ldap_version;
00199
00200
00201
00202
00203 if (strlen(ldap_config.s) == 0)
00204 {
00205 LM_ERR("config_file is empty - this module param is mandatory\n");
00206 return -2;
00207 }
00208 if ((config_vals = iniparser_new(ldap_config.s)) == NULL)
00209 {
00210 LM_ERR("failed to read config_file [%s]\n", ldap_config.s);
00211 return -2;
00212 }
00213 if ((ld_count = iniparser_getnsec(config_vals)) < 1)
00214 {
00215 LM_ERR("no section found in config_file [%s]\n", ldap_config.s);
00216 return -2;
00217 }
00218
00219 for (i = 0; i < ld_count; i++)
00220 {
00221 section_name = iniparser_getsecname(config_vals, i);
00222 if (strlen(section_name) > 255)
00223 {
00224 LM_ERR( "config_file section name [%s]"
00225 " longer than allowed 255 characters",
00226 section_name);
00227 return -2;
00228 }
00229 if (!iniparser_find_entry(config_vals,
00230 get_ini_key_name(section_name, CFG_N_LDAP_HOST)))
00231 {
00232 LM_ERR( "mandatory %s not defined in [%s]\n",
00233 CFG_N_LDAP_HOST,
00234 section_name);
00235 return -2;
00236 }
00237 }
00238
00239
00240
00241
00242 if (ldap_get_vendor_version(&ldap_version) != 0)
00243 {
00244 LM_ERR("ldap_get_vendor_version failed\n");
00245 return -2;
00246 }
00247 LM_INFO("%s\n", ldap_version);
00248
00249 return 0;
00250 }
00251
00252
00253 static void destroy(void)
00254 {
00255
00256 free_ld_sessions();
00257
00258
00259 iniparser_free(config_vals);
00260 }
00261
00262
00263
00264
00265
00266
00267 static int w_ldap_search(struct sip_msg* msg, char* ldap_url, char* param)
00268 {
00269 return ldap_search_impl(msg, (pv_elem_t*)ldap_url);
00270 }
00271
00272 static int w_ldap_result1(struct sip_msg* msg, char* src, char* param)
00273 {
00274 return ldap_write_result(msg, (struct ldap_result_params*)src, NULL);
00275 }
00276
00277 static int w_ldap_result2(struct sip_msg* msg, char* src, char* subst)
00278 {
00279 return ldap_write_result(msg, (struct ldap_result_params*)src,
00280 (struct subst_expr*)subst);
00281 }
00282
00283 static int w_ldap_result_next(struct sip_msg* msg, char* foo, char *bar)
00284 {
00285 return ldap_result_next();
00286 }
00287
00288 static int w_ldap_filter_url_encode(struct sip_msg* msg,
00289 char* filter_component, char* dst_avp_name)
00290 {
00291 return ldap_filter_url_encode(msg, (pv_elem_t*)filter_component,
00292 (pv_spec_t*)dst_avp_name);
00293 }
00294
00295 static int w_ldap_result_check_1(struct sip_msg* msg,
00296 char* attr_name_check_str, char* param)
00297 {
00298 return ldap_result_check(msg,
00299 (struct ldap_result_check_params*)attr_name_check_str, NULL);
00300 }
00301
00302 static int w_ldap_result_check_2(struct sip_msg* msg,
00303 char* attr_name_check_str, char* attr_val_re)
00304 {
00305 return ldap_result_check( msg,
00306 (struct ldap_result_check_params*)attr_name_check_str,
00307 (struct subst_expr*)attr_val_re);
00308 }
00309
00310
00311
00312
00313
00314 static int ldap_search_fixup(void** param, int param_no)
00315 {
00316 pv_elem_t *model;
00317 str s;
00318
00319 if (param_no == 1) {
00320 s.s = (char*)*param;
00321 s.len = strlen(s.s);
00322 if (s.len==0) {
00323 LM_ERR("ldap url is empty string!\n");
00324 return E_CFG;
00325 }
00326 if ( pv_parse_format(&s,&model) || model==NULL) {
00327 LM_ERR("wrong format [%s] for ldap url!\n", s.s);
00328 return E_CFG;
00329 }
00330 *param = (void*)model;
00331 }
00332
00333 return 0;
00334 }
00335
00336 static int ldap_result_fixup(void** param, int param_no)
00337 {
00338 struct ldap_result_params* lp;
00339 struct subst_expr* se;
00340 str subst;
00341 char *arg_str, *dst_avp_str, *dst_avp_val_type_str;
00342 char *p;
00343 str s;
00344 int dst_avp_val_type = 0;
00345
00346 if (param_no == 1) {
00347 arg_str = (char*)*param;
00348 if ((dst_avp_str = strchr(arg_str, '/')) == 0)
00349 {
00350
00351 LM_ERR("invalid first argument [%s]\n", arg_str);
00352 return E_UNSPEC;
00353 }
00354 *(dst_avp_str++) = 0;
00355
00356 if ((dst_avp_val_type_str = strchr(dst_avp_str, '/')))
00357 {
00358 *(dst_avp_val_type_str++) = 0;
00359 if (!strcmp(dst_avp_val_type_str, "int"))
00360 {
00361 dst_avp_val_type = 1;
00362 }
00363 else if (strcmp(dst_avp_val_type_str, "str"))
00364 {
00365 LM_ERR( "invalid avp_type [%s]\n",
00366 dst_avp_val_type_str);
00367 return E_UNSPEC;
00368 }
00369 }
00370
00371 lp = (struct ldap_result_params*)pkg_malloc(sizeof(struct ldap_result_params));
00372 if (lp == NULL) {
00373 LM_ERR("no memory\n");
00374 return E_OUT_OF_MEM;
00375 }
00376 memset(lp, 0, sizeof(struct ldap_result_params));
00377
00378 lp->ldap_attr_name.s = arg_str;
00379 lp->ldap_attr_name.len = strlen(arg_str);
00380
00381 lp->dst_avp_val_type = dst_avp_val_type;
00382 s.s = dst_avp_str; s.len = strlen(s.s);
00383 p = pv_parse_spec(&s, &lp->dst_avp_spec);
00384 if (p == 0) {
00385 pkg_free(lp);
00386 LM_ERR("parse error for [%s]\n",
00387 dst_avp_str);
00388 return E_UNSPEC;
00389 }
00390 if (lp->dst_avp_spec.type != PVT_AVP) {
00391 pkg_free(lp);
00392 LM_ERR( "bad attribute name [%s]\n",
00393 dst_avp_str);
00394 return E_UNSPEC;
00395 }
00396 *param = (void*)lp;
00397
00398 } else if (param_no == 2) {
00399 subst.s = *param;
00400 subst.len = strlen(*param);
00401 se = subst_parser(&subst);
00402 if (se == 0) {
00403 LM_ERR("bad subst re [%s]\n",
00404 (char*)*param);
00405 return E_BAD_RE;
00406 }
00407 *param = (void*)se;
00408 }
00409
00410 return 0;
00411 }
00412
00413 static int ldap_result_check_fixup(void** param, int param_no)
00414 {
00415 struct ldap_result_check_params *lp;
00416 struct subst_expr *se;
00417 str subst;
00418 str s;
00419 char *arg_str, *check_str;
00420 int arg_str_len;
00421
00422 if (param_no == 1)
00423 {
00424 arg_str = (char*)*param;
00425 arg_str_len = strlen(arg_str);
00426 if ((check_str = strchr(arg_str, '/')) == 0)
00427 {
00428
00429 LM_ERR( "invalid first argument [%s] (no '/' found)\n",
00430 arg_str);
00431 return E_UNSPEC;
00432 }
00433 *(check_str++) = 0;
00434
00435 lp = (struct ldap_result_check_params*)pkg_malloc(sizeof(struct ldap_result_check_params));
00436 if (lp == NULL) {
00437 LM_ERR("no memory\n");
00438 return E_OUT_OF_MEM;
00439 }
00440 memset(lp, 0, sizeof(struct ldap_result_check_params));
00441
00442 lp->ldap_attr_name.s = arg_str;
00443 lp->ldap_attr_name.len = strlen(arg_str);
00444
00445 if (lp->ldap_attr_name.len + 1 == arg_str_len)
00446 {
00447
00448 lp->check_str_elem_p = 0;
00449 }
00450 else
00451 {
00452 s.s = check_str; s.len = strlen(s.s);
00453 if (pv_parse_format(&s, &(lp->check_str_elem_p)) < 0)
00454 {
00455 LM_ERR("pv_parse_format failed\n");
00456 return E_OUT_OF_MEM;
00457 }
00458 }
00459 *param = (void*)lp;
00460 }
00461 else if (param_no == 2)
00462 {
00463 subst.s = *param;
00464 subst.len = strlen(*param);
00465 se = subst_parser(&subst);
00466 if (se == 0) {
00467 LM_ERR( "bad subst re [%s]\n",
00468 (char*)*param);
00469 return E_BAD_RE;
00470 }
00471 *param = (void*)se;
00472 }
00473
00474 return 0;
00475 }
00476
00477 static int ldap_filter_url_encode_fixup(void** param, int param_no)
00478 {
00479 pv_elem_t *elem_p;
00480 pv_spec_t *spec_p;
00481 str s;
00482
00483 if (param_no == 1) {
00484 s.s = (char*)*param;
00485 if (s.s==0 || s.s[0]==0) {
00486 elem_p = 0;
00487 } else {
00488 s.len = strlen(s.s);
00489 if (pv_parse_format(&s, &elem_p) < 0) {
00490 LM_ERR("pv_parse_format failed\n");
00491 return E_OUT_OF_MEM;
00492 }
00493 }
00494 *param = (void*)elem_p;
00495 }
00496 else if (param_no == 2)
00497 {
00498 spec_p = (pv_spec_t*)pkg_malloc(sizeof(pv_spec_t));
00499 if (spec_p == NULL) {
00500 LM_ERR("no memory\n");
00501 return E_OUT_OF_MEM;
00502 }
00503 s.s = (char*)*param; s.len = strlen(s.s);
00504 if (pv_parse_spec(&s, spec_p)
00505 == 0)
00506 {
00507 pkg_free(spec_p);
00508 LM_ERR("parse error for [%s]\n",
00509 (char*)*param);
00510 return E_UNSPEC;
00511 }
00512 if (spec_p->type != PVT_AVP) {
00513 pkg_free(spec_p);
00514 LM_ERR("bad attribute name"
00515 " [%s]\n", (char*)*param);
00516 return E_UNSPEC;
00517 }
00518 *param = (void*)spec_p;
00519 }
00520
00521 return 0;
00522 }