ldap.c 7.1 KB

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