vtable.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463
  1. /** BEGIN COPYRIGHT BLOCK
  2. * This Program is free software; you can redistribute it and/or modify it under
  3. * the terms of the GNU General Public License as published by the Free Software
  4. * Foundation; version 2 of the License.
  5. *
  6. * This Program is distributed in the hope that it will be useful, but WITHOUT
  7. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  8. * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  9. *
  10. * You should have received a copy of the GNU General Public License along with
  11. * this Program; if not, write to the Free Software Foundation, Inc., 59 Temple
  12. * Place, Suite 330, Boston, MA 02111-1307 USA.
  13. *
  14. * In addition, as a special exception, Red Hat, Inc. gives You the additional
  15. * right to link the code of this Program with code not covered under the GNU
  16. * General Public License ("Non-GPL Code") and to distribute linked combinations
  17. * including the two, subject to the limitations in this paragraph. Non-GPL Code
  18. * permitted under this exception must only link to the code of this Program
  19. * through those well defined interfaces identified in the file named EXCEPTION
  20. * found in the source code files (the "Approved Interfaces"). The files of
  21. * Non-GPL Code may instantiate templates or use macros or inline functions from
  22. * the Approved Interfaces without causing the resulting work to be covered by
  23. * the GNU General Public License. Only Red Hat, Inc. may make changes or
  24. * additions to the list of Approved Interfaces. You must obey the GNU General
  25. * Public License in all respects for all of the Program code and other code used
  26. * in conjunction with the Program except the Non-GPL Code covered by this
  27. * exception. If you modify this file, you may extend this exception to your
  28. * version of the file, but you are not obligated to do so. If you do not wish to
  29. * provide this exception without modification, you must delete this exception
  30. * statement from your version and license this file solely under the GPL without
  31. * exception.
  32. *
  33. *
  34. * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
  35. * Copyright (C) 2005 Red Hat, Inc.
  36. * All rights reserved.
  37. * END COPYRIGHT BLOCK **/
  38. #ifdef HAVE_CONFIG_H
  39. # include <config.h>
  40. #endif
  41. #include "ldaputili.h"
  42. #include <ldap.h>
  43. #ifdef USE_LDAP_SSL
  44. #include <ldap_ssl.h>
  45. #endif
  46. #if defined( _WINDOWS ) && ! defined( _WIN32 )
  47. /* On 16-bit WINDOWS platforms, it's erroneous to call LDAP API functions
  48. * via a function pointer, since they are not declared LDAP_CALLBACK.
  49. * So, we define the following functions, which are LDAP_CALLBACK, and
  50. * simply delegate to their counterparts in the LDAP API.
  51. */
  52. #ifdef USE_LDAP_SSL
  53. static LDAP_CALL LDAP_CALLBACK LDAP*
  54. ldapuVd_ssl_init( const char *host, int port, int encrypted )
  55. {
  56. return ldapssl_init (host, port, encrypted);
  57. }
  58. #else
  59. static LDAP_CALL LDAP_CALLBACK LDAP*
  60. ldapuVd_init ( const char *host, int port )
  61. {
  62. return ldap_init (host, port);
  63. }
  64. #endif
  65. static LDAP_CALL LDAP_CALLBACK int
  66. ldapuVd_set_option( LDAP *ld, int opt, const void *val )
  67. {
  68. return ldap_set_option (ld, opt, val);
  69. }
  70. static LDAP_CALL LDAP_CALLBACK int
  71. ldapuVd_simple_bind_s( LDAP* ld, const char *username, const char *passwd )
  72. {
  73. return ldap_simple_bind_s (ld, username, passwd);
  74. }
  75. static LDAP_CALL LDAP_CALLBACK int
  76. ldapuVd_unbind( LDAP *ld )
  77. {
  78. return ldap_unbind (ld);
  79. }
  80. static LDAP_CALL LDAP_CALLBACK int
  81. ldapuVd_search_s( LDAP* ld, const char* baseDN, int scope, const char* filter,
  82. char** attrs, int attrsonly, LDAPMessage** result )
  83. {
  84. return ldap_search_s (ld, baseDN, scope, filter, attrs, attrsonly, result);
  85. }
  86. static LDAP_CALL LDAP_CALLBACK int
  87. ldapuVd_count_entries( LDAP* ld, LDAPMessage* msg )
  88. {
  89. return ldap_count_entries (ld, msg);
  90. }
  91. static LDAP_CALL LDAP_CALLBACK LDAPMessage*
  92. ldapuVd_first_entry( LDAP* ld, LDAPMessage* msg )
  93. {
  94. return ldap_first_entry (ld, msg);
  95. }
  96. static LDAP_CALL LDAP_CALLBACK LDAPMessage*
  97. ldapuVd_next_entry( LDAP* ld, LDAPMessage* entry )
  98. {
  99. return ldap_next_entry(ld, entry);
  100. }
  101. static LDAP_CALL LDAP_CALLBACK char*
  102. ldapuVd_get_dn( LDAP* ld, LDAPMessage* entry )
  103. {
  104. return ldap_get_dn (ld, entry);
  105. }
  106. static LDAP_CALL LDAP_CALLBACK char*
  107. ldapuVd_first_attribute( LDAP* ld, LDAPMessage* entry, BerElement** iter )
  108. {
  109. return ldap_first_attribute (ld, entry, iter);
  110. }
  111. static LDAP_CALL LDAP_CALLBACK char*
  112. ldapuVd_next_attribute( LDAP* ld, LDAPMessage* entry, BerElement* iter)
  113. {
  114. return ldap_next_attribute (ld, entry, iter);
  115. }
  116. static LDAP_CALL LDAP_CALLBACK char**
  117. ldapuVd_get_values( LDAP *ld, LDAPMessage *entry, const char *desc )
  118. {
  119. return ldap_get_values (ld, entry, desc);
  120. }
  121. static LDAP_CALL LDAP_CALLBACK struct berval**
  122. ldapuVd_get_values_len( LDAP *ld, LDAPMessage *entry, const char *desc )
  123. {
  124. return ldap_get_values_len (ld, entry, desc);
  125. }
  126. #else
  127. /* On other platforms, an LDAP API function can be called via a pointer. */
  128. #ifdef USE_LDAP_SSL
  129. #define ldapuVd_ssl_init ldapssl_init
  130. #else
  131. #define ldapuVd_init ldap_init
  132. #endif
  133. #define ldapuVd_set_option ldap_set_option
  134. #define ldapuVd_simple_bind_s ldap_simple_bind_s
  135. #define ldapuVd_unbind ldap_unbind
  136. #define ldapuVd_simple_bind_s ldap_simple_bind_s
  137. #define ldapuVd_unbind ldap_unbind
  138. #define ldapuVd_search_s ldap_search_s
  139. #define ldapuVd_count_entries ldap_count_entries
  140. #define ldapuVd_first_entry ldap_first_entry
  141. #define ldapuVd_next_entry ldap_next_entry
  142. #define ldapuVd_get_dn ldap_get_dn
  143. #define ldapuVd_first_attribute ldap_first_attribute
  144. #define ldapuVd_next_attribute ldap_next_attribute
  145. #define ldapuVd_get_values ldap_get_values
  146. #define ldapuVd_get_values_len ldap_get_values_len
  147. #endif
  148. /* Several functions in the standard LDAP API have no LDAP* parameter,
  149. but all the VTable functions do. Here are some little functions that
  150. make up the difference, by ignoring their LDAP* parameter:
  151. */
  152. static int LDAP_CALL LDAP_CALLBACK
  153. ldapuVd_msgfree( LDAP *ld, LDAPMessage *chain )
  154. {
  155. return ldap_msgfree (chain);
  156. }
  157. static void LDAP_CALL LDAP_CALLBACK
  158. ldapuVd_memfree( LDAP *ld, void *dn )
  159. {
  160. ldap_memfree (dn);
  161. }
  162. static void LDAP_CALL LDAP_CALLBACK
  163. ldapuVd_ber_free( LDAP *ld, BerElement *ber, int freebuf )
  164. {
  165. ldap_ber_free (ber, freebuf);
  166. }
  167. static void LDAP_CALL LDAP_CALLBACK
  168. ldapuVd_value_free( LDAP *ld, char **vals )
  169. {
  170. ldap_value_free (vals);
  171. }
  172. static void LDAP_CALL LDAP_CALLBACK
  173. ldapuVd_value_free_len( LDAP *ld, struct berval **vals )
  174. {
  175. ldap_value_free_len (vals);
  176. }
  177. static LDAPUVTable_t ldapu_VTable = {
  178. /* By default, the VTable points to the standard LDAP API. */
  179. #ifdef USE_LDAP_SSL
  180. ldapuVd_ssl_init,
  181. #else
  182. ldapuVd_init,
  183. #endif
  184. ldapuVd_set_option,
  185. ldapuVd_simple_bind_s,
  186. ldapuVd_unbind,
  187. ldapuVd_search_s,
  188. ldapuVd_count_entries,
  189. ldapuVd_first_entry,
  190. ldapuVd_next_entry,
  191. ldapuVd_msgfree,
  192. ldapuVd_get_dn,
  193. ldapuVd_memfree,
  194. ldapuVd_first_attribute,
  195. ldapuVd_next_attribute,
  196. ldapuVd_ber_free,
  197. ldapuVd_get_values,
  198. ldapuVd_value_free,
  199. ldapuVd_get_values_len,
  200. ldapuVd_value_free_len
  201. };
  202. /* Replace ldapu_VTable. Subsequently, ldaputil will call the
  203. functions in 'from' (not the LDAP API) to access the directory.
  204. */
  205. void
  206. ldapu_VTable_set (LDAPUVTable_t* from)
  207. {
  208. if (from) {
  209. memcpy (&ldapu_VTable, from, sizeof(LDAPUVTable_t));
  210. }
  211. }
  212. #ifdef USE_LDAP_SSL
  213. LDAP*
  214. ldapu_ssl_init( const char *defhost, int defport, int defsecure )
  215. {
  216. if (ldapu_VTable.ldapuV_ssl_init) {
  217. return ldapu_VTable.ldapuV_ssl_init (defhost, defport, defsecure);
  218. }
  219. return NULL;
  220. }
  221. #else
  222. LDAP*
  223. ldapu_init( const char *defhost, int defport )
  224. {
  225. if (ldapu_VTable.ldapuV_init) {
  226. return ldapu_VTable.ldapuV_init (defhost, defport);
  227. }
  228. return NULL;
  229. }
  230. #endif
  231. int
  232. ldapu_set_option( LDAP *ld, int option, void *optdata )
  233. {
  234. if (ldapu_VTable.ldapuV_set_option) {
  235. return ldapu_VTable.ldapuV_set_option (ld, option, optdata);
  236. }
  237. return LDAP_LOCAL_ERROR;
  238. }
  239. int
  240. ldapu_simple_bind_s( LDAP *ld, const char *who, const char *passwd )
  241. {
  242. if (ldapu_VTable.ldapuV_simple_bind_s) {
  243. return ldapu_VTable.ldapuV_simple_bind_s (ld, who, passwd);
  244. }
  245. return LDAP_LOCAL_ERROR;
  246. }
  247. int
  248. ldapu_unbind( LDAP *ld )
  249. {
  250. if (ldapu_VTable.ldapuV_unbind) {
  251. return ldapu_VTable.ldapuV_unbind (ld);
  252. }
  253. return LDAP_LOCAL_ERROR;
  254. }
  255. int
  256. ldapu_search_s( LDAP *ld, const char *base, int scope,
  257. const char *filter, char **attrs, int attrsonly, LDAPMessage **res )
  258. {
  259. if (ldapu_VTable.ldapuV_search_s) {
  260. return ldapu_VTable.ldapuV_search_s (ld, base, scope, filter, attrs, attrsonly, res);
  261. }
  262. return LDAP_LOCAL_ERROR;
  263. }
  264. int
  265. ldapu_count_entries( LDAP *ld, LDAPMessage *chain )
  266. {
  267. if (ldapu_VTable.ldapuV_count_entries) {
  268. return ldapu_VTable.ldapuV_count_entries (ld, chain);
  269. }
  270. return 0;
  271. }
  272. LDAPMessage*
  273. ldapu_first_entry( LDAP *ld, LDAPMessage *chain )
  274. {
  275. if (ldapu_VTable.ldapuV_first_entry) {
  276. return ldapu_VTable.ldapuV_first_entry (ld, chain);
  277. }
  278. return NULL;
  279. }
  280. LDAPMessage*
  281. ldapu_next_entry( LDAP *ld, LDAPMessage *entry )
  282. {
  283. if (ldapu_VTable.ldapuV_next_entry) {
  284. return ldapu_VTable.ldapuV_next_entry (ld, entry);
  285. }
  286. return NULL;
  287. }
  288. int
  289. ldapu_msgfree( LDAP* ld, LDAPMessage *chain )
  290. {
  291. if (ldapu_VTable.ldapuV_msgfree) {
  292. return ldapu_VTable.ldapuV_msgfree (ld, chain);
  293. }
  294. return LDAP_SUCCESS;
  295. }
  296. char*
  297. ldapu_get_dn( LDAP *ld, LDAPMessage *entry )
  298. {
  299. if (ldapu_VTable.ldapuV_get_dn) {
  300. return ldapu_VTable.ldapuV_get_dn (ld, entry);
  301. }
  302. return NULL;
  303. }
  304. void
  305. ldapu_memfree( LDAP* ld, void *p )
  306. {
  307. if (ldapu_VTable.ldapuV_memfree) {
  308. ldapu_VTable.ldapuV_memfree (ld, p);
  309. }
  310. }
  311. char*
  312. ldapu_first_attribute( LDAP *ld, LDAPMessage *entry, BerElement **ber )
  313. {
  314. if (ldapu_VTable.ldapuV_first_attribute) {
  315. return ldapu_VTable.ldapuV_first_attribute (ld, entry, ber);
  316. }
  317. return NULL;
  318. }
  319. char*
  320. ldapu_next_attribute( LDAP *ld, LDAPMessage *entry, BerElement *ber )
  321. {
  322. if (ldapu_VTable.ldapuV_next_attribute) {
  323. return ldapu_VTable.ldapuV_next_attribute (ld, entry, ber);
  324. }
  325. return NULL;
  326. }
  327. void
  328. ldapu_ber_free( LDAP* ld, BerElement *ber, int freebuf )
  329. {
  330. if (ldapu_VTable.ldapuV_ber_free) {
  331. ldapu_VTable.ldapuV_ber_free (ld, ber, freebuf);
  332. }
  333. }
  334. char**
  335. ldapu_get_values( LDAP *ld, LDAPMessage *entry, const char *desc )
  336. {
  337. if (ldapu_VTable.ldapuV_get_values) {
  338. return ldapu_VTable.ldapuV_get_values (ld, entry, desc);
  339. } else if (!ldapu_VTable.ldapuV_value_free
  340. && ldapu_VTable.ldapuV_get_values_len) {
  341. auto struct berval** bvals =
  342. ldapu_VTable.ldapuV_get_values_len (ld, entry, desc);
  343. if (bvals) {
  344. auto char** vals = (char**)
  345. ldapu_malloc ((ldap_count_values_len (bvals) + 1)
  346. * sizeof(char*));
  347. if (vals) {
  348. auto char** val;
  349. auto struct berval** bval;
  350. for (val = vals, bval = bvals; *bval; ++val, ++bval) {
  351. auto const size_t len = (*bval)->bv_len;
  352. *val = (char*) ldapu_malloc (len + 1);
  353. memcpy (*val, (*bval)->bv_val, len);
  354. (*val)[len] = '\0';
  355. }
  356. *val = NULL;
  357. ldapu_value_free_len(ld, bvals);
  358. return vals;
  359. }
  360. }
  361. ldapu_value_free_len(ld, bvals);
  362. }
  363. return NULL;
  364. }
  365. void
  366. ldapu_value_free( LDAP *ld, char **vals )
  367. {
  368. if (ldapu_VTable.ldapuV_value_free) {
  369. ldapu_VTable.ldapuV_value_free (ld, vals);
  370. } else if (!ldapu_VTable.ldapuV_get_values && vals) {
  371. auto char** val;
  372. for (val = vals; *val; ++val) {
  373. free (*val);
  374. }
  375. free (vals);
  376. }
  377. }
  378. struct berval**
  379. ldapu_get_values_len( LDAP *ld, LDAPMessage *entry, const char *desc )
  380. {
  381. if (ldapu_VTable.ldapuV_get_values_len) {
  382. return ldapu_VTable.ldapuV_get_values_len (ld, entry, desc);
  383. } else if (!ldapu_VTable.ldapuV_value_free_len
  384. && ldapu_VTable.ldapuV_get_values) {
  385. auto char** vals =
  386. ldapu_VTable.ldapuV_get_values (ld, entry, desc);
  387. if (vals) {
  388. auto struct berval** bvals = (struct berval**)
  389. ldapu_malloc ((ldap_count_values (vals) + 1)
  390. * sizeof(struct berval*));
  391. if (bvals) {
  392. auto char** val;
  393. auto struct berval** bval;
  394. for (val = vals, bval = bvals; *val; ++val, ++bval) {
  395. auto const size_t len = strlen(*val);
  396. *bval = (struct berval*) ldapu_malloc (sizeof(struct berval) + len);
  397. (*bval)->bv_len = len;
  398. (*bval)->bv_val = ((char*)(*bval)) + sizeof(struct berval);
  399. memcpy ((*bval)->bv_val, *val, len);
  400. }
  401. *bval = NULL;
  402. return bvals;
  403. }
  404. }
  405. }
  406. return NULL;
  407. }
  408. void
  409. ldapu_value_free_len( LDAP *ld, struct berval **vals )
  410. {
  411. if (ldapu_VTable.ldapuV_value_free_len) {
  412. ldapu_VTable.ldapuV_value_free_len (ld, vals);
  413. } else if (!ldapu_VTable.ldapuV_get_values_len && vals) {
  414. auto struct berval** val;
  415. for (val = vals; *val; ++val) {
  416. free (*val);
  417. }
  418. free (vals);
  419. }
  420. }