ldap_connect.c 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311
  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 <unistd.h>
  33. #include <stdio.h>
  34. #include <ldap.h>
  35. #include "ldap_connect.h"
  36. #include "ld_session.h"
  37. #include "../../mem/mem.h"
  38. #include "../../ut.h"
  39. int ldap_connect(char* _ld_name)
  40. {
  41. int rc;
  42. int ldap_bind_result_code;
  43. char *ldap_err_str;
  44. int ldap_proto_version;
  45. int msgid;
  46. LDAPMessage *result;
  47. struct ld_session* lds;
  48. struct berval ldap_cred;
  49. /*
  50. * get ld session and session config parameters
  51. */
  52. if ((lds = get_ld_session(_ld_name)) == NULL)
  53. {
  54. LM_ERR("ld_session [%s] not found\n", _ld_name);
  55. return -1;
  56. }
  57. /*
  58. * ldap_initialize
  59. */
  60. rc = ldap_initialize(&lds->handle, lds->host_name);
  61. if (rc != LDAP_SUCCESS)
  62. {
  63. LM_ERR( "[%s]: ldap_initialize (%s) failed: %s\n",
  64. _ld_name,
  65. lds->host_name,
  66. ldap_err2string(rc));
  67. return -1;
  68. }
  69. /*
  70. * set LDAP OPTIONS
  71. */
  72. /* LDAP_OPT_PROTOCOL_VERSION */
  73. switch (lds->version) {
  74. case 2:
  75. ldap_proto_version = LDAP_VERSION2;
  76. break;
  77. case 3:
  78. ldap_proto_version = LDAP_VERSION3;
  79. break;
  80. default:
  81. LM_ERR( "[%s]: Invalid LDAP protocol version [%d]\n",
  82. _ld_name,
  83. lds->version);
  84. return -1;
  85. }
  86. if (ldap_set_option(lds->handle,
  87. LDAP_OPT_PROTOCOL_VERSION,
  88. &ldap_proto_version)
  89. != LDAP_OPT_SUCCESS)
  90. {
  91. LM_ERR( "[%s]: Could not set LDAP_OPT_PROTOCOL_VERSION [%d]\n",
  92. _ld_name,
  93. ldap_proto_version);
  94. return -1;
  95. }
  96. /* LDAP_OPT_RESTART */
  97. if (ldap_set_option(lds->handle,
  98. LDAP_OPT_RESTART,
  99. LDAP_OPT_ON)
  100. != LDAP_OPT_SUCCESS) {
  101. LM_ERR("[%s]: Could not set LDAP_OPT_RESTART to ON\n", _ld_name);
  102. return -1;
  103. }
  104. /* LDAP_OPT_TIMELIMIT */
  105. /*
  106. if (lds->server_search_timeout > 0) {
  107. if (ldap_set_option(lds->handle,
  108. LDAP_OPT_TIMELIMIT,
  109. &lds->server_search_timeout)
  110. != LDAP_OPT_SUCCESS) {
  111. LM_ERR("[%s]: Could not set LDAP_OPT_TIMELIMIT to [%d]\n",
  112. _ld_name, lds->server_search_timeout);
  113. return -1;
  114. }
  115. }
  116. */
  117. /* LDAP_OPT_NETWORK_TIMEOUT */
  118. if ((lds->network_timeout.tv_sec > 0) || (lds->network_timeout.tv_usec > 0))
  119. {
  120. if (ldap_set_option(lds->handle,
  121. LDAP_OPT_NETWORK_TIMEOUT,
  122. (const void *)&lds->network_timeout)
  123. != LDAP_OPT_SUCCESS)
  124. {
  125. LM_ERR( "[%s]: Could not set"
  126. " LDAP_NETWORK_TIMEOUT to [%d.%d]\n",
  127. _ld_name,
  128. (int)lds->network_timeout.tv_sec,
  129. (int)lds->network_timeout.tv_usec);
  130. }
  131. }
  132. /*
  133. * ldap_sasl_bind (LDAP_SASL_SIMPLE)
  134. */
  135. ldap_cred.bv_val = lds->bind_pwd;
  136. ldap_cred.bv_len = strlen(lds->bind_pwd);
  137. rc = ldap_sasl_bind(
  138. lds->handle,
  139. lds->bind_dn,
  140. LDAP_SASL_SIMPLE,
  141. &ldap_cred,
  142. NULL,
  143. NULL,
  144. &msgid);
  145. if (rc != LDAP_SUCCESS)
  146. {
  147. LM_ERR( "[%s]: ldap bind failed: %s\n",
  148. _ld_name,
  149. ldap_err2string(rc));
  150. return -1;
  151. }
  152. if ((lds->client_bind_timeout.tv_sec == 0)
  153. && (lds->client_bind_timeout.tv_usec == 0))
  154. {
  155. rc = ldap_result(lds->handle, msgid, 1, NULL, &result);
  156. } else
  157. {
  158. rc = ldap_result(lds->handle, msgid, 1, &lds->client_bind_timeout,
  159. &result);
  160. }
  161. if (rc == -1)
  162. {
  163. ldap_get_option(lds->handle, LDAP_OPT_ERROR_NUMBER, &rc);
  164. ldap_err_str = ldap_err2string(rc);
  165. LM_ERR( "[%s]: ldap_result failed: %s\n",
  166. _ld_name,
  167. ldap_err_str);
  168. return -1;
  169. }
  170. else if (rc == 0)
  171. {
  172. LM_ERR("[%s]: bind operation timed out\n", _ld_name);
  173. return -1;
  174. }
  175. rc = ldap_parse_result(
  176. lds->handle,
  177. result,
  178. &ldap_bind_result_code,
  179. NULL,
  180. NULL,
  181. NULL,
  182. NULL,
  183. 1);
  184. if (rc != LDAP_SUCCESS)
  185. {
  186. LM_ERR( "[%s]: ldap_parse_result failed: %s\n",
  187. _ld_name,
  188. ldap_err2string(rc));
  189. return -1;
  190. }
  191. if (ldap_bind_result_code != LDAP_SUCCESS)
  192. {
  193. LM_ERR( "[%s]: ldap bind failed: %s\n",
  194. _ld_name,
  195. ldap_err2string(ldap_bind_result_code));
  196. return -1;
  197. }
  198. /* freeing result leads to segfault ... bind result is probably used by openldap lib */
  199. /* ldap_msgfree(result); */
  200. LM_DBG( "[%s]: LDAP bind successful (ldap_host [%s])\n",
  201. _ld_name,
  202. lds->host_name);
  203. return 0;
  204. }
  205. int ldap_disconnect(char* _ld_name)
  206. {
  207. struct ld_session* lds;
  208. /*
  209. * get ld session
  210. */
  211. if ((lds = get_ld_session(_ld_name)) == NULL)
  212. {
  213. LM_ERR("ld_session [%s] not found\n", _ld_name);
  214. return -1;
  215. }
  216. if (lds->handle == NULL) {
  217. return 0;
  218. }
  219. ldap_unbind_ext(lds->handle, NULL, NULL);
  220. lds->handle = NULL;
  221. return 0;
  222. }
  223. int ldap_reconnect(char* _ld_name)
  224. {
  225. int rc;
  226. if (ldap_disconnect(_ld_name) != 0)
  227. {
  228. LM_ERR("[%s]: disconnect failed\n", _ld_name);
  229. return -1;
  230. }
  231. if ((rc = ldap_connect(_ld_name)) != 0)
  232. {
  233. LM_ERR("[%s]: reconnect failed\n",
  234. _ld_name);
  235. }
  236. else
  237. {
  238. LM_ERR("[%s]: LDAP reconnect successful\n",
  239. _ld_name);
  240. }
  241. return rc;
  242. }
  243. int ldap_get_vendor_version(char** _version)
  244. {
  245. static char version[128];
  246. LDAPAPIInfo api;
  247. int rc;
  248. #ifdef LDAP_API_INFO_VERSION
  249. api.ldapai_info_version = LDAP_API_INFO_VERSION;
  250. #else
  251. api.ldapai_info_version = 1;
  252. #endif
  253. if (ldap_get_option(NULL, LDAP_OPT_API_INFO, &api) != LDAP_SUCCESS)
  254. {
  255. LM_ERR("ldap_get_option(API_INFO) failed\n");
  256. return -1;
  257. }
  258. rc = snprintf(version, 128, "%s - %d", api.ldapai_vendor_name,
  259. api.ldapai_vendor_version);
  260. if ((rc >= 128) || (rc < 0))
  261. {
  262. LM_ERR("snprintf failed\n");
  263. return -1;
  264. }
  265. *_version = version;
  266. return 0;
  267. }