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==PROC_INIT || rank==PROC_MAIN || rank==PROC_TCP_MAIN)
00162 return 0;
00163
00164
00165
00166
00167 ld_count = iniparser_getnsec(config_vals);
00168 for (i = 0; i < ld_count; i++)
00169 {
00170 ld_name = iniparser_getsecname(config_vals, i);
00171 if (add_ld_session(ld_name,
00172 NULL,
00173 config_vals)
00174 != 0)
00175 {
00176 LM_ERR("[%s]: add_ld_session failed\n", ld_name);
00177 return -1;
00178 }
00179
00180 if (ldap_connect(ld_name) != 0)
00181 {
00182 LM_ERR("[%s]: failed to connect to LDAP host(s)\n", ld_name);
00183 ldap_disconnect(ld_name);
00184 return -1;
00185 }
00186
00187 }
00188
00189 return 0;
00190 }
00191
00192
00193 static int mod_init(void)
00194 {
00195 int ld_count = 0, i = 0;
00196 char* section_name;
00197 char* ldap_version;
00198
00199
00200
00201
00202 if (strlen(ldap_config.s) == 0)
00203 {
00204 LM_ERR("config_file is empty - this module param is mandatory\n");
00205 return -2;
00206 }
00207 if ((config_vals = iniparser_new(ldap_config.s)) == NULL)
00208 {
00209 LM_ERR("failed to read config_file [%s]\n", ldap_config.s);
00210 return -2;
00211 }
00212 if ((ld_count = iniparser_getnsec(config_vals)) < 1)
00213 {
00214 LM_ERR("no section found in config_file [%s]\n", ldap_config.s);
00215 return -2;
00216 }
00217
00218 for (i = 0; i < ld_count; i++)
00219 {
00220 section_name = iniparser_getsecname(config_vals, i);
00221 if (strlen(section_name) > 255)
00222 {
00223 LM_ERR( "config_file section name [%s]"
00224 " longer than allowed 255 characters",
00225 section_name);
00226 return -2;
00227 }
00228 if (!iniparser_find_entry(config_vals,
00229 get_ini_key_name(section_name, CFG_N_LDAP_HOST)))
00230 {
00231 LM_ERR( "mandatory %s not defined in [%s]\n",
00232 CFG_N_LDAP_HOST,
00233 section_name);
00234 return -2;
00235 }
00236 }
00237
00238
00239
00240
00241 if (ldap_get_vendor_version(&ldap_version) != 0)
00242 {
00243 LM_ERR("ldap_get_vendor_version failed\n");
00244 return -2;
00245 }
00246 LM_INFO("%s\n", ldap_version);
00247
00248 return 0;
00249 }
00250
00251
00252 static void destroy(void)
00253 {
00254
00255 free_ld_sessions();
00256
00257
00258 iniparser_free(config_vals);
00259 }
00260
00261
00262
00263
00264
00265
00266 static int w_ldap_search(struct sip_msg* msg, char* ldap_url, char* param)
00267 {
00268 return ldap_search_impl(msg, (pv_elem_t*)ldap_url);
00269 }
00270
00271 static int w_ldap_result1(struct sip_msg* msg, char* src, char* param)
00272 {
00273 return ldap_write_result(msg, (struct ldap_result_params*)src, NULL);
00274 }
00275
00276 static int w_ldap_result2(struct sip_msg* msg, char* src, char* subst)
00277 {
00278 return ldap_write_result(msg, (struct ldap_result_params*)src,
00279 (struct subst_expr*)subst);
00280 }
00281
00282 static int w_ldap_result_next(struct sip_msg* msg, char* foo, char *bar)
00283 {
00284 return ldap_result_next();
00285 }
00286
00287 static int w_ldap_filter_url_encode(struct sip_msg* msg,
00288 char* filter_component, char* dst_avp_name)
00289 {
00290 return ldap_filter_url_encode(msg, (pv_elem_t*)filter_component,
00291 (pv_spec_t*)dst_avp_name);
00292 }
00293
00294 static int w_ldap_result_check_1(struct sip_msg* msg,
00295 char* attr_name_check_str, char* param)
00296 {
00297 return ldap_result_check(msg,
00298 (struct ldap_result_check_params*)attr_name_check_str, NULL);
00299 }
00300
00301 static int w_ldap_result_check_2(struct sip_msg* msg,
00302 char* attr_name_check_str, char* attr_val_re)
00303 {
00304 return ldap_result_check( msg,
00305 (struct ldap_result_check_params*)attr_name_check_str,
00306 (struct subst_expr*)attr_val_re);
00307 }
00308
00309
00310
00311
00312
00313 static int ldap_search_fixup(void** param, int param_no)
00314 {
00315 pv_elem_t *model;
00316 str s;
00317
00318 if (param_no == 1) {
00319 s.s = (char*)*param;
00320 s.len = strlen(s.s);
00321 if (s.len==0) {
00322 LM_ERR("ldap url is empty string!\n");
00323 return E_CFG;
00324 }
00325 if ( pv_parse_format(&s,&model) || model==NULL) {
00326 LM_ERR("wrong format [%s] for ldap url!\n", s.s);
00327 return E_CFG;
00328 }
00329 *param = (void*)model;
00330 }
00331
00332 return 0;
00333 }
00334
00335 static int ldap_result_fixup(void** param, int param_no)
00336 {
00337 struct ldap_result_params* lp;
00338 struct subst_expr* se;
00339 str subst;
00340 char *arg_str, *dst_avp_str, *dst_avp_val_type_str;
00341 char *p;
00342 str s;
00343 int dst_avp_val_type = 0;
00344
00345 if (param_no == 1) {
00346 arg_str = (char*)*param;
00347 if ((dst_avp_str = strchr(arg_str, '/')) == 0)
00348 {
00349
00350 LM_ERR("invalid first argument [%s]\n", arg_str);
00351 return E_UNSPEC;
00352 }
00353 *(dst_avp_str++) = 0;
00354
00355 if ((dst_avp_val_type_str = strchr(dst_avp_str, '/')))
00356 {
00357 *(dst_avp_val_type_str++) = 0;
00358 if (!strcmp(dst_avp_val_type_str, "int"))
00359 {
00360 dst_avp_val_type = 1;
00361 }
00362 else if (strcmp(dst_avp_val_type_str, "str"))
00363 {
00364 LM_ERR( "invalid avp_type [%s]\n",
00365 dst_avp_val_type_str);
00366 return E_UNSPEC;
00367 }
00368 }
00369
00370 lp = (struct ldap_result_params*)pkg_malloc(sizeof(struct ldap_result_params));
00371 if (lp == NULL) {
00372 LM_ERR("no memory\n");
00373 return E_OUT_OF_MEM;
00374 }
00375 memset(lp, 0, sizeof(struct ldap_result_params));
00376
00377 lp->ldap_attr_name.s = arg_str;
00378 lp->ldap_attr_name.len = strlen(arg_str);
00379
00380 lp->dst_avp_val_type = dst_avp_val_type;
00381 s.s = dst_avp_str; s.len = strlen(s.s);
00382 p = pv_parse_spec(&s, &lp->dst_avp_spec);
00383 if (p == 0) {
00384 pkg_free(lp);
00385 LM_ERR("parse error for [%s]\n",
00386 dst_avp_str);
00387 return E_UNSPEC;
00388 }
00389 if (lp->dst_avp_spec.type != PVT_AVP) {
00390 pkg_free(lp);
00391 LM_ERR( "bad attribute name [%s]\n",
00392 dst_avp_str);
00393 return E_UNSPEC;
00394 }
00395 *param = (void*)lp;
00396
00397 } else if (param_no == 2) {
00398 subst.s = *param;
00399 subst.len = strlen(*param);
00400 se = subst_parser(&subst);
00401 if (se == 0) {
00402 LM_ERR("bad subst re [%s]\n",
00403 (char*)*param);
00404 return E_BAD_RE;
00405 }
00406 *param = (void*)se;
00407 }
00408
00409 return 0;
00410 }
00411
00412 static int ldap_result_check_fixup(void** param, int param_no)
00413 {
00414 struct ldap_result_check_params *lp;
00415 struct subst_expr *se;
00416 str subst;
00417 str s;
00418 char *arg_str, *check_str;
00419 int arg_str_len;
00420
00421 if (param_no == 1)
00422 {
00423 arg_str = (char*)*param;
00424 arg_str_len = strlen(arg_str);
00425 if ((check_str = strchr(arg_str, '/')) == 0)
00426 {
00427
00428 LM_ERR( "invalid first argument [%s] (no '/' found)\n",
00429 arg_str);
00430 return E_UNSPEC;
00431 }
00432 *(check_str++) = 0;
00433
00434 lp = (struct ldap_result_check_params*)pkg_malloc(sizeof(struct ldap_result_check_params));
00435 if (lp == NULL) {
00436 LM_ERR("no memory\n");
00437 return E_OUT_OF_MEM;
00438 }
00439 memset(lp, 0, sizeof(struct ldap_result_check_params));
00440
00441 lp->ldap_attr_name.s = arg_str;
00442 lp->ldap_attr_name.len = strlen(arg_str);
00443
00444 if (lp->ldap_attr_name.len + 1 == arg_str_len)
00445 {
00446
00447 lp->check_str_elem_p = 0;
00448 }
00449 else
00450 {
00451 s.s = check_str; s.len = strlen(s.s);
00452 if (pv_parse_format(&s, &(lp->check_str_elem_p)) < 0)
00453 {
00454 LM_ERR("pv_parse_format failed\n");
00455 return E_OUT_OF_MEM;
00456 }
00457 }
00458 *param = (void*)lp;
00459 }
00460 else if (param_no == 2)
00461 {
00462 subst.s = *param;
00463 subst.len = strlen(*param);
00464 se = subst_parser(&subst);
00465 if (se == 0) {
00466 LM_ERR( "bad subst re [%s]\n",
00467 (char*)*param);
00468 return E_BAD_RE;
00469 }
00470 *param = (void*)se;
00471 }
00472
00473 return 0;
00474 }
00475
00476 static int ldap_filter_url_encode_fixup(void** param, int param_no)
00477 {
00478 pv_elem_t *elem_p;
00479 pv_spec_t *spec_p;
00480 str s;
00481
00482 if (param_no == 1) {
00483 s.s = (char*)*param;
00484 if (s.s==0 || s.s[0]==0) {
00485 elem_p = 0;
00486 } else {
00487 s.len = strlen(s.s);
00488 if (pv_parse_format(&s, &elem_p) < 0) {
00489 LM_ERR("pv_parse_format failed\n");
00490 return E_OUT_OF_MEM;
00491 }
00492 }
00493 *param = (void*)elem_p;
00494 }
00495 else if (param_no == 2)
00496 {
00497 spec_p = (pv_spec_t*)pkg_malloc(sizeof(pv_spec_t));
00498 if (spec_p == NULL) {
00499 LM_ERR("no memory\n");
00500 return E_OUT_OF_MEM;
00501 }
00502 s.s = (char*)*param; s.len = strlen(s.s);
00503 if (pv_parse_spec(&s, spec_p)
00504 == 0)
00505 {
00506 pkg_free(spec_p);
00507 LM_ERR("parse error for [%s]\n",
00508 (char*)*param);
00509 return E_UNSPEC;
00510 }
00511 if (spec_p->type != PVT_AVP) {
00512 pkg_free(spec_p);
00513 LM_ERR("bad attribute name"
00514 " [%s]\n", (char*)*param);
00515 return E_UNSPEC;
00516 }
00517 *param = (void*)spec_p;
00518 }
00519
00520 return 0;
00521 }