ldap.c 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  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. (fnc) = (type)DynaGetFunction(#fnc); \
  52. if ((fnc) == NULL) { \
  53. return CURLE_FUNCTION_NOT_FOUND; \
  54. } \
  55. /***********************************************************************
  56. */
  57. static void *libldap = NULL;
  58. static void *liblber = NULL;
  59. static void DynaOpen(void)
  60. {
  61. (void)liblber;
  62. #if defined(HAVE_DLOPEN) || defined(HAVE_LIBDL)
  63. if (libldap == NULL) {
  64. /*
  65. * libldap.so should be able to resolve its dependency on
  66. * liblber.so automatically, but since it does not we will
  67. * handle it here by opening liblber.so as global.
  68. */
  69. dlopen("liblber.so",
  70. #ifdef RTLD_LAZY_GLOBAL /* It turns out some systems use this: */
  71. RTLD_LAZY_GLOBAL
  72. #else
  73. #ifdef RTLD_GLOBAL
  74. RTLD_LAZY | RTLD_GLOBAL
  75. #else
  76. /* and some systems don't have the RTLD_GLOBAL symbol */
  77. RTLD_LAZY
  78. #endif
  79. #endif
  80. );
  81. libldap = dlopen("libldap.so", RTLD_LAZY);
  82. }
  83. #endif
  84. }
  85. static void DynaClose(void)
  86. {
  87. #if defined(HAVE_DLOPEN) || defined(HAVE_LIBDL)
  88. if (libldap) {
  89. dlclose(libldap);
  90. libldap=NULL;
  91. }
  92. if (liblber) {
  93. dlclose(liblber);
  94. liblber=NULL;
  95. }
  96. #endif
  97. }
  98. static void * DynaGetFunction(const char *name)
  99. {
  100. void *func = NULL;
  101. (void)name;
  102. #if defined(HAVE_DLOPEN) || defined(HAVE_LIBDL)
  103. if (libldap) {
  104. func = dlsym(libldap, name);
  105. }
  106. #endif
  107. return func;
  108. }
  109. static int WriteProc(void *param, char *text, int len)
  110. {
  111. struct SessionHandle *data = (struct SessionHandle *)param;
  112. len = 0; /* prevent compiler warning */
  113. Curl_client_write(data, CLIENTWRITE_BODY, text, 0);
  114. return 0;
  115. }
  116. /***********************************************************************
  117. */
  118. CURLcode Curl_ldap(struct connectdata *conn)
  119. {
  120. CURLcode status = CURLE_OK;
  121. int rc;
  122. void *(*ldap_open)(char *, int);
  123. int (*ldap_simple_bind_s)(void *, char *, char *);
  124. int (*ldap_unbind_s)(void *);
  125. int (*ldap_url_search_s)(void *, char *, int, void **);
  126. void *(*ldap_first_entry)(void *, void *);
  127. void *(*ldap_next_entry)(void *, void *);
  128. char *(*ldap_err2string)(int);
  129. int (*ldap_entry2text)(void *, char *, void *, void *, char **, char **, int (*)(void *, char *, int), void *, char *, int, unsigned long);
  130. int (*ldap_entry2html)(void *, char *, void *, void *, char **, char **, int (*)(void *, char *, int), void *, char *, int, unsigned long, char *, char *);
  131. void *server;
  132. void *result;
  133. void *entryIterator;
  134. int ldaptext;
  135. struct SessionHandle *data=conn->data;
  136. infof(data, "LDAP: %s\n", data->change.url);
  137. DynaOpen();
  138. if (libldap == NULL) {
  139. failf(data, "The needed LDAP library/libraries couldn't be opened");
  140. return CURLE_LIBRARY_NOT_FOUND;
  141. }
  142. ldaptext = data->set.ftp_ascii; /* This is a dirty hack */
  143. /* The types are needed because ANSI C distinguishes between
  144. * pointer-to-object (data) and pointer-to-function.
  145. */
  146. DYNA_GET_FUNCTION(void *(*)(char *, int), ldap_open);
  147. DYNA_GET_FUNCTION(int (*)(void *, char *, char *), ldap_simple_bind_s);
  148. DYNA_GET_FUNCTION(int (*)(void *), ldap_unbind_s);
  149. DYNA_GET_FUNCTION(int (*)(void *, char *, int, void **), ldap_url_search_s);
  150. DYNA_GET_FUNCTION(void *(*)(void *, void *), ldap_first_entry);
  151. DYNA_GET_FUNCTION(void *(*)(void *, void *), ldap_next_entry);
  152. DYNA_GET_FUNCTION(char *(*)(int), ldap_err2string);
  153. DYNA_GET_FUNCTION(int (*)(void *, char *, void *, void *, char **, char **, int (*)(void *, char *, int), void *, char *, int, unsigned long), ldap_entry2text);
  154. DYNA_GET_FUNCTION(int (*)(void *, char *, void *, void *, char **, char **, int (*)(void *, char *, int), void *, char *, int, unsigned long, char *, char *), ldap_entry2html);
  155. server = ldap_open(conn->hostname, conn->port);
  156. if (server == NULL) {
  157. failf(data, "LDAP: Cannot connect to %s:%d",
  158. conn->hostname, conn->port);
  159. status = CURLE_COULDNT_CONNECT;
  160. } else {
  161. rc = ldap_simple_bind_s(server,
  162. conn->bits.user_passwd?data->state.user:NULL,
  163. conn->bits.user_passwd?data->state.passwd:NULL);
  164. if (rc != 0) {
  165. failf(data, "LDAP: %s", ldap_err2string(rc));
  166. status = CURLE_LDAP_CANNOT_BIND;
  167. } else {
  168. rc = ldap_url_search_s(server, data->change.url, 0, &result);
  169. if (rc != 0) {
  170. failf(data, "LDAP: %s", ldap_err2string(rc));
  171. status = CURLE_LDAP_SEARCH_FAILED;
  172. } else {
  173. for (entryIterator = ldap_first_entry(server, result);
  174. entryIterator;
  175. entryIterator = ldap_next_entry(server, entryIterator))
  176. {
  177. if (ldaptext) {
  178. rc = ldap_entry2text(server, NULL, entryIterator, NULL,
  179. NULL, NULL, WriteProc, data,
  180. (char *)"", 0, 0);
  181. if (rc != 0) {
  182. failf(data, "LDAP: %s", ldap_err2string(rc));
  183. status = CURLE_LDAP_SEARCH_FAILED;
  184. }
  185. } else {
  186. rc = ldap_entry2html(server, NULL, entryIterator, NULL,
  187. NULL, NULL, WriteProc, data,
  188. (char *)"", 0, 0, NULL, NULL);
  189. if (rc != 0) {
  190. failf(data, "LDAP: %s", ldap_err2string(rc));
  191. status = CURLE_LDAP_SEARCH_FAILED;
  192. }
  193. }
  194. }
  195. }
  196. ldap_unbind_s(server);
  197. }
  198. }
  199. DynaClose();
  200. /* no data to transfer */
  201. Curl_Transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
  202. return status;
  203. }
  204. /*
  205. * local variables:
  206. * eval: (load-file "../curl-mode.el")
  207. * end:
  208. * vim600: fdm=marker
  209. * vim: et sw=2 ts=2 sts=2 tw=78
  210. */
  211. #endif