ldap_exp_fn.c 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375
  1. /*
  2. * $Id$
  3. *
  4. * Kamailio LDAP Module
  5. *
  6. * Copyright (C) 2007 University of North Carolina
  7. *
  8. * Original author: Christian Schlatter, [email protected]
  9. *
  10. *
  11. * This file is part of Kamailio, a free SIP server.
  12. *
  13. * Kamailio is free software; you can redistribute it and/or modify
  14. * it under the terms of the GNU General Public License as published by
  15. * the Free Software Foundation; either version 2 of the License, or
  16. * (at your option) any later version
  17. *
  18. * Kamailio is distributed in the hope that it will be useful,
  19. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  20. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  21. * GNU General Public License for more details.
  22. *
  23. * You should have received a copy of the GNU General Public License
  24. * along with this program; if not, write to the Free Software
  25. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  26. *
  27. * History:
  28. * --------
  29. * 2007-02-18: Initial version
  30. */
  31. #include <string.h>
  32. #include <stdio.h>
  33. #include <ldap.h>
  34. #include "../../ut.h"
  35. #include "../../str.h"
  36. #include "../../pvar.h"
  37. #include "../../usr_avp.h"
  38. #include "../../mem/mem.h"
  39. #include "ldap_exp_fn.h"
  40. #include "ldap_connect.h"
  41. #include "ldap_api_fn.h"
  42. #include "ldap_escape.h"
  43. #define STR_BUF_SIZE 1024
  44. #define ESC_BUF_SIZE 65536
  45. static char str_buf[STR_BUF_SIZE];
  46. static char esc_buf[ESC_BUF_SIZE];
  47. /*
  48. * exported functions
  49. */
  50. int ldap_search_impl(
  51. struct sip_msg* _msg,
  52. pv_elem_t* _ldap_url)
  53. {
  54. str ldap_url;
  55. int ld_result_count = 0;
  56. /*
  57. * do variable substitution for _ldap_url (pv_printf_s)
  58. */
  59. if (_ldap_url==NULL) {
  60. LM_ERR("empty ldap_url\n");
  61. return -2;
  62. }
  63. if ( _ldap_url->spec!=NULL && _ldap_url->spec->getf!=NULL) {
  64. if (pv_printf_s( _msg, _ldap_url, &ldap_url)!=0 || ldap_url.len<=0) {
  65. LM_ERR("pv_printf_s failed\n");
  66. return -2;
  67. }
  68. } else {
  69. ldap_url = _ldap_url->text;
  70. }
  71. /*
  72. * perform LDAP search
  73. */
  74. if (ldap_url_search(ldap_url.s, &ld_result_count) != 0)
  75. {
  76. /* LDAP search error */
  77. return -2;
  78. }
  79. if (ld_result_count < 1)
  80. {
  81. /* no LDAP entry found */
  82. LM_INFO("no LDAP entry found\n");
  83. return -1;
  84. }
  85. return ld_result_count;
  86. }
  87. int ldap_write_result(
  88. struct sip_msg* _msg,
  89. struct ldap_result_params* _lrp,
  90. struct subst_expr* _se)
  91. {
  92. int_str dst_avp_name, dst_avp_val;
  93. unsigned short dst_avp_type;
  94. int nmatches, rc, i, added_avp_count = 0;
  95. struct berval **attr_vals;
  96. str avp_val_str, *subst_result = NULL;
  97. int avp_val_int;
  98. /*
  99. * get dst AVP name (dst_avp_name)
  100. */
  101. if (pv_get_avp_name( _msg,
  102. &(_lrp->dst_avp_spec.pvp),
  103. &dst_avp_name,
  104. &dst_avp_type)
  105. != 0)
  106. {
  107. LM_ERR("error getting dst AVP name\n");
  108. return -2;
  109. }
  110. if (dst_avp_type & AVP_NAME_STR)
  111. {
  112. if (dst_avp_name.s.len >= STR_BUF_SIZE)
  113. {
  114. LM_ERR("dst AVP name too long\n");
  115. return -2;
  116. }
  117. strncpy(str_buf, dst_avp_name.s.s, dst_avp_name.s.len);
  118. str_buf[dst_avp_name.s.len] = '\0';
  119. dst_avp_name.s.s = str_buf;
  120. }
  121. /*
  122. * get LDAP attr values
  123. */
  124. if ((rc = ldap_get_attr_vals(&_lrp->ldap_attr_name, &attr_vals)) != 0)
  125. {
  126. if (rc > 0) {
  127. return -1;
  128. } else {
  129. return -2;
  130. }
  131. }
  132. /*
  133. * add AVPs
  134. */
  135. for (i = 0; attr_vals[i] != NULL; i++)
  136. {
  137. if (_se == NULL)
  138. {
  139. avp_val_str.s = attr_vals[i]->bv_val;
  140. avp_val_str.len = attr_vals[i]->bv_len;
  141. }
  142. else
  143. {
  144. subst_result = subst_str(attr_vals[i]->bv_val, _msg, _se,
  145. &nmatches);
  146. if ((subst_result == NULL) || (nmatches < 1))
  147. {
  148. continue;
  149. }
  150. avp_val_str = *subst_result;
  151. }
  152. if (_lrp->dst_avp_val_type == 1)
  153. {
  154. /* try to convert ldap value to integer */
  155. if (!str2sint(&avp_val_str, &avp_val_int))
  156. {
  157. dst_avp_val.n = avp_val_int;
  158. rc = add_avp(dst_avp_type, dst_avp_name, dst_avp_val);
  159. } else
  160. {
  161. continue;
  162. }
  163. } else
  164. {
  165. /* save ldap value as string */
  166. dst_avp_val.s = avp_val_str;
  167. rc = add_avp(dst_avp_type|AVP_VAL_STR, dst_avp_name, dst_avp_val);
  168. }
  169. if (subst_result != NULL) {
  170. if (subst_result->s != 0) {
  171. pkg_free(subst_result->s);
  172. }
  173. pkg_free(subst_result);
  174. subst_result = NULL;
  175. }
  176. if (rc < 0)
  177. {
  178. LM_ERR("failed to create new AVP\n");
  179. ldap_value_free_len(attr_vals);
  180. return -2;
  181. }
  182. added_avp_count++;
  183. }
  184. ldap_value_free_len(attr_vals);
  185. if (added_avp_count > 0)
  186. {
  187. return added_avp_count;
  188. } else
  189. {
  190. return -1;
  191. }
  192. }
  193. int ldap_result_next(void)
  194. {
  195. int rc;
  196. rc = ldap_inc_result_pointer();
  197. switch (rc)
  198. {
  199. case 1:
  200. return -1;
  201. case 0:
  202. return 1;
  203. case -1:
  204. default:
  205. return -2;
  206. }
  207. }
  208. int ldap_result_check(
  209. struct sip_msg* _msg,
  210. struct ldap_result_check_params* _lrp,
  211. struct subst_expr* _se)
  212. {
  213. str check_str, *subst_result = NULL;
  214. int rc, i, nmatches;
  215. char *attr_val;
  216. struct berval **attr_vals;
  217. /*
  218. * do variable substitution for check_str
  219. */
  220. if (_lrp->check_str_elem_p)
  221. {
  222. if (pv_printf_s(_msg, _lrp->check_str_elem_p, &check_str) != 0)
  223. {
  224. LM_ERR("pv_printf_s failed\n");
  225. return -2;
  226. }
  227. } else
  228. {
  229. LM_ERR("empty check string\n");
  230. return -2;
  231. }
  232. LM_DBG("check_str [%s]\n", check_str.s);
  233. /*
  234. * get LDAP attr values
  235. */
  236. if ((rc = ldap_get_attr_vals(&_lrp->ldap_attr_name, &attr_vals)) != 0)
  237. {
  238. if (rc > 0) {
  239. return -1;
  240. } else {
  241. return -2;
  242. }
  243. }
  244. /*
  245. * loop through attribute values
  246. */
  247. for (i = 0; attr_vals[i] != NULL; i++)
  248. {
  249. if (_se == NULL)
  250. {
  251. attr_val = attr_vals[i]->bv_val;
  252. } else
  253. {
  254. subst_result = subst_str(attr_vals[i]->bv_val, _msg, _se,
  255. &nmatches);
  256. if ((subst_result == NULL) || (nmatches < 1))
  257. {
  258. continue;
  259. }
  260. attr_val = subst_result->s;
  261. }
  262. LM_DBG("attr_val [%s]\n", attr_val);
  263. rc = strncmp(check_str.s, attr_val, check_str.len);
  264. if (_se != NULL)
  265. {
  266. pkg_free(subst_result->s);
  267. }
  268. if (rc == 0)
  269. {
  270. ldap_value_free_len(attr_vals);
  271. return 1;
  272. }
  273. }
  274. ldap_value_free_len(attr_vals);
  275. return -1;
  276. }
  277. int ldap_filter_url_encode(
  278. struct sip_msg* _msg,
  279. pv_elem_t* _filter_component,
  280. pv_spec_t* _dst_avp_spec)
  281. {
  282. str filter_component_str, esc_str;
  283. int_str dst_avp_name;
  284. unsigned short dst_avp_type;
  285. /*
  286. * variable substitution for _filter_component
  287. */
  288. if (_filter_component) {
  289. if (pv_printf_s(_msg, _filter_component, &filter_component_str) != 0) {
  290. LM_ERR("pv_printf_s failed\n");
  291. return -1;
  292. }
  293. } else {
  294. LM_ERR("empty first argument\n");
  295. return -1;
  296. }
  297. /*
  298. * get dst AVP name (dst_avp_name)
  299. */
  300. if (pv_get_avp_name(_msg, &(_dst_avp_spec->pvp), &dst_avp_name,
  301. &dst_avp_type) != 0)
  302. {
  303. LM_ERR("error getting dst AVP name\n");
  304. return -1;
  305. }
  306. if (dst_avp_type & AVP_NAME_STR)
  307. {
  308. if (dst_avp_name.s.len >= STR_BUF_SIZE)
  309. {
  310. LM_ERR("dst AVP name too long\n");
  311. return -1;
  312. }
  313. strncpy(str_buf, dst_avp_name.s.s, dst_avp_name.s.len);
  314. str_buf[dst_avp_name.s.len] = '\0';
  315. dst_avp_name.s.s = str_buf;
  316. }
  317. /*
  318. * apply LDAP filter escaping rules
  319. */
  320. esc_str.s = esc_buf;
  321. esc_str.len = ESC_BUF_SIZE;
  322. if (ldap_rfc4515_escape(&filter_component_str, &esc_str, 1) != 0)
  323. {
  324. LM_ERR("ldap_rfc4515_escape() failed\n");
  325. return -1;
  326. }
  327. /*
  328. * add dst AVP
  329. */
  330. if (add_avp(dst_avp_type|AVP_VAL_STR, dst_avp_name, (int_str)esc_str) != 0)
  331. {
  332. LM_ERR("failed to add new AVP\n");
  333. return -1;
  334. }
  335. return 1;
  336. }