ldap.c 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. /***************************************************************************
  2. * _ _ ____ _
  3. * Project ___| | | | _ \| |
  4. * / __| | | | |_) | |
  5. * | (__| |_| | _ <| |___
  6. * \___|\___/|_| \_\_____|
  7. *
  8. * Copyright (C) 1998 - 2002, Daniel Stenberg, <[email protected]>, et al.
  9. *
  10. * This software is licensed as described in the file COPYING, which
  11. * you should have received as part of this distribution. The terms
  12. * are also available at http://curl.haxx.se/docs/copyright.html.
  13. *
  14. * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  15. * copies of the Software, and permit persons to whom the Software is
  16. * furnished to do so, under the terms of the COPYING file.
  17. *
  18. * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
  19. * KIND, either express or implied.
  20. *
  21. * $Id$
  22. ***************************************************************************/
  23. #include "setup.h"
  24. #ifndef CURL_DISABLE_LDAP
  25. /* -- WIN32 approved -- */
  26. #include <stdio.h>
  27. #include <string.h>
  28. #include <stdarg.h>
  29. #include <stdlib.h>
  30. #include <ctype.h>
  31. #include <sys/types.h>
  32. #include <sys/stat.h>
  33. #include <errno.h>
  34. #if defined(WIN32) && !defined(__GNUC__)
  35. #else
  36. # ifdef HAVE_UNISTD_H
  37. # include <unistd.h>
  38. # endif
  39. # ifdef HAVE_DLFCN_H
  40. # include <dlfcn.h>
  41. # endif
  42. #endif
  43. #include "urldata.h"
  44. #include <curl/curl.h>
  45. #include "sendf.h"
  46. #include "escape.h"
  47. #include "transfer.h"
  48. #define _MPRINTF_REPLACE /* use our functions only */
  49. #include <curl/mprintf.h>
  50. #define DYNA_GET_FUNCTION(type, fnc) \
  51. { \
  52. void* dyna_get_res = DynaGetFunction(#fnc); \
  53. (fnc) = *((type)&dyna_get_res); \
  54. if ((fnc) == NULL) { \
  55. return CURLE_FUNCTION_NOT_FOUND; \
  56. } \
  57. }
  58. /***********************************************************************
  59. */
  60. static void *libldap = NULL;
  61. static void *liblber = NULL;
  62. static void DynaOpen(void)
  63. {
  64. (void)liblber;
  65. #if defined(HAVE_DLOPEN) || defined(HAVE_LIBDL)
  66. if (libldap == NULL) {
  67. /*
  68. * libldap.so should be able to resolve its dependency on
  69. * liblber.so automatically, but since it does not we will
  70. * handle it here by opening liblber.so as global.
  71. */
  72. dlopen("liblber.so",
  73. #ifdef RTLD_LAZY_GLOBAL /* It turns out some systems use this: */
  74. RTLD_LAZY_GLOBAL
  75. #else
  76. #ifdef RTLD_GLOBAL
  77. RTLD_LAZY | RTLD_GLOBAL
  78. #else
  79. /* and some systems don't have the RTLD_GLOBAL symbol */
  80. RTLD_LAZY
  81. #endif
  82. #endif
  83. );
  84. libldap = dlopen("libldap.so", RTLD_LAZY);
  85. }
  86. #endif
  87. }
  88. static void DynaClose(void)
  89. {
  90. #if defined(HAVE_DLOPEN) || defined(HAVE_LIBDL)
  91. if (libldap) {
  92. dlclose(libldap);
  93. libldap=NULL;
  94. }
  95. if (liblber) {
  96. dlclose(liblber);
  97. liblber=NULL;
  98. }
  99. #endif
  100. }
  101. static void * DynaGetFunction(const char *name)
  102. {
  103. void *func = NULL;
  104. (void)name;
  105. #if defined(HAVE_DLOPEN) || defined(HAVE_LIBDL)
  106. if (libldap) {
  107. func = dlsym(libldap, name);
  108. }
  109. #endif
  110. return func;
  111. }
  112. static int WriteProc(void *param, char *text, int len)
  113. {
  114. struct SessionHandle *data = (struct SessionHandle *)param;
  115. len = 0; /* prevent compiler warning */
  116. Curl_client_write(data, CLIENTWRITE_BODY, text, 0);
  117. return 0;
  118. }
  119. /***********************************************************************
  120. */
  121. CURLcode Curl_ldap(struct connectdata *conn)
  122. {
  123. CURLcode status = CURLE_OK;
  124. int rc;
  125. void *(*ldap_open)(char *, int);
  126. int (*ldap_simple_bind_s)(void *, char *, char *);
  127. int (*ldap_unbind_s)(void *);
  128. int (*ldap_url_search_s)(void *, char *, int, void **);
  129. void *(*ldap_first_entry)(void *, void *);
  130. void *(*ldap_next_entry)(void *, void *);
  131. char *(*ldap_err2string)(int);
  132. int (*ldap_entry2text)(void *, char *, void *, void *, char **, char **, int (*)(void *, char *, int), void *, char *, int, unsigned long);
  133. int (*ldap_entry2html)(void *, char *, void *, void *, char **, char **, int (*)(void *, char *, int), void *, char *, int, unsigned long, char *, char *);
  134. void *server;
  135. void *result;
  136. void *entryIterator;
  137. int ldaptext;
  138. struct SessionHandle *data=conn->data;
  139. infof(data, "LDAP: %s\n", data->change.url);
  140. DynaOpen();
  141. if (libldap == NULL) {
  142. failf(data, "The needed LDAP library/libraries couldn't be opened");
  143. return CURLE_LIBRARY_NOT_FOUND;
  144. }
  145. ldaptext = data->set.ftp_ascii; /* This is a dirty hack */
  146. /* The types are needed because ANSI C distinguishes between
  147. * pointer-to-object (data) and pointer-to-function.
  148. */
  149. DYNA_GET_FUNCTION(void *(**)(char *, int), ldap_open);
  150. DYNA_GET_FUNCTION(int (**)(void *, char *, char *), ldap_simple_bind_s);
  151. DYNA_GET_FUNCTION(int (**)(void *), ldap_unbind_s);
  152. DYNA_GET_FUNCTION(int (**)(void *, char *, int, void **), ldap_url_search_s);
  153. DYNA_GET_FUNCTION(void *(**)(void *, void *), ldap_first_entry);
  154. DYNA_GET_FUNCTION(void *(**)(void *, void *), ldap_next_entry);
  155. DYNA_GET_FUNCTION(char *(**)(int), ldap_err2string);
  156. DYNA_GET_FUNCTION(int (**)(void *, char *, void *, void *, char **, char **, int (*)(void *, char *, int), void *, char *, int, unsigned long), ldap_entry2text);
  157. DYNA_GET_FUNCTION(int (**)(void *, char *, void *, void *, char **, char **, int (*)(void *, char *, int), void *, char *, int, unsigned long, char *, char *), ldap_entry2html);
  158. server = ldap_open(conn->hostname, conn->port);
  159. if (server == NULL) {
  160. failf(data, "LDAP: Cannot connect to %s:%d",
  161. conn->hostname, conn->port);
  162. status = CURLE_COULDNT_CONNECT;
  163. } else {
  164. rc = ldap_simple_bind_s(server,
  165. conn->bits.user_passwd?data->state.user:NULL,
  166. conn->bits.user_passwd?data->state.passwd:NULL);
  167. if (rc != 0) {
  168. failf(data, "LDAP: %s", ldap_err2string(rc));
  169. status = CURLE_LDAP_CANNOT_BIND;
  170. } else {
  171. rc = ldap_url_search_s(server, data->change.url, 0, &result);
  172. if (rc != 0) {
  173. failf(data, "LDAP: %s", ldap_err2string(rc));
  174. status = CURLE_LDAP_SEARCH_FAILED;
  175. } else {
  176. for (entryIterator = ldap_first_entry(server, result);
  177. entryIterator;
  178. entryIterator = ldap_next_entry(server, entryIterator))
  179. {
  180. if (ldaptext) {
  181. rc = ldap_entry2text(server, NULL, entryIterator, NULL,
  182. NULL, NULL, WriteProc, data,
  183. (char *)"", 0, 0);
  184. if (rc != 0) {
  185. failf(data, "LDAP: %s", ldap_err2string(rc));
  186. status = CURLE_LDAP_SEARCH_FAILED;
  187. }
  188. } else {
  189. rc = ldap_entry2html(server, NULL, entryIterator, NULL,
  190. NULL, NULL, WriteProc, data,
  191. (char *)"", 0, 0, NULL, NULL);
  192. if (rc != 0) {
  193. failf(data, "LDAP: %s", ldap_err2string(rc));
  194. status = CURLE_LDAP_SEARCH_FAILED;
  195. }
  196. }
  197. }
  198. }
  199. ldap_unbind_s(server);
  200. }
  201. }
  202. DynaClose();
  203. /* no data to transfer */
  204. Curl_Transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
  205. return status;
  206. }
  207. /*
  208. * local variables:
  209. * eval: (load-file "../curl-mode.el")
  210. * end:
  211. * vim600: fdm=marker
  212. * vim: et sw=2 ts=2 sts=2 tw=78
  213. */
  214. #endif