ldap.c 7.0 KB

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