testdatainterop.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344
  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) 2005 Red Hat, Inc.
  35. * All rights reserved.
  36. * END COPYRIGHT BLOCK **/
  37. /******** testdatainterop.c *******************
  38. This source file provides an example of a plug-in function
  39. that implements an datainteroprability functionality.
  40. The plug-in function is called by the server
  41. when the server is configured to use the null dn.
  42. meaning dn:
  43. The server uses the null dn or the root suffix opnly when
  44. the configuration for the server has the following
  45. node in the dse.ldif of the server instance
  46. (in the <server_root>/slapd-<server_id>/config directory).
  47. dn: cn="",cn=mapping tree,cn=config
  48. objectClass: top
  49. objectClass: extensibleObject
  50. objectClass: nsMappingTree
  51. cn: ""
  52. nsslapd-state: container
  53. The plugin below is a pre-operation plugin which
  54. provides alternate functionality for the LDAP operations
  55. of search, modify, add etc. that are targeted at the root-suffix
  56. or the null-dn to be serviced by an alternate data source or
  57. alternate access methods allowing datainteroperability.
  58. The example below creates a berkely db and modifies or adds data
  59. to the db demonstarting the use of an alternate data source seperate
  60. from the Directory Server. Also, the results of a search operation
  61. are completely in the control of the pre-operation plugin. In this
  62. example a fake entry is returned to express the functionality
  63. To test this plug-in function, stop the server, edit the dse.ldif file
  64. (in the <server_root>/slapd-<server_id>/config directory)
  65. and add the following lines before restarting the server :
  66. dn: cn="",cn=mapping tree,cn=config
  67. objectClass: top
  68. objectClass: extensibleObject
  69. objectClass: nsMappingTree
  70. cn: ""
  71. nsslapd-state: container
  72. dn: cn=datainterop,cn=plugins,cn=config
  73. objectClass: top
  74. objectClass: nsSlapdPlugin
  75. cn: datainterop
  76. nsslapd-pluginPath: <server-root>/plugins/slapd/slapi/examples/libtest-plugin.so
  77. nsslapd-pluginInitfunc: nullsuffix_init
  78. nsslapd-pluginType: preoperation
  79. nsslapd-pluginEnabled: on
  80. nsslapd-pluginId: nullsuffix-preop
  81. nsslapd-pluginVersion: 7.1
  82. nsslapd-pluginVendor: Fedora Project
  83. nsslapd-pluginDescription: sample pre-operation null suffix plugin
  84. ******************************************/
  85. #include <stdio.h>
  86. #include <string.h>
  87. #include "slapi-plugin.h"
  88. /*
  89. * Macros.
  90. */
  91. #define PLUGIN_NAME "nullsuffix-preop"
  92. #define PLUGIN_OPERATION_HANDLED 1
  93. #define PLUGIN_OPERATION_IGNORED 0
  94. #define SEARCH_SCOPE_ANY (-1)
  95. /*
  96. * Static variables.
  97. */
  98. static Slapi_PluginDesc plugindesc = { PLUGIN_NAME, "Fedora Project", "1.0.2",
  99. "sample pre-operation null suffix plugin" };
  100. static Slapi_ComponentId *plugin_id = NULL;
  101. /*
  102. * Function prototypes.
  103. */
  104. static int nullsuffix_search( Slapi_PBlock *pb );
  105. static int nullsuffix_add( Slapi_PBlock *pb );
  106. static int nullsuffix_close( Slapi_PBlock *pb );
  107. static int nullsuffix_modify( Slapi_PBlock *pb );
  108. static int nullsuffix_delete( Slapi_PBlock *pb );
  109. static int nullsuffix_modrdn( Slapi_PBlock *pb );
  110. static int nullsuffix_bind( Slapi_PBlock *pb );
  111. /*
  112. * Initialization function.
  113. */
  114. #ifdef _WIN32
  115. __declspec(dllexport)
  116. #endif
  117. int
  118. nullsuffix_init( Slapi_PBlock *pb )
  119. {
  120. int i;
  121. slapi_log_error( SLAPI_LOG_PLUGIN, PLUGIN_NAME, "nullsuffix_init\n" );
  122. /* retrieve plugin identity to later pass to internal operations */
  123. if ( slapi_pblock_get( pb, SLAPI_PLUGIN_IDENTITY, &plugin_id ) != 0 ) {
  124. slapi_log_error( SLAPI_LOG_PLUGIN, PLUGIN_NAME,
  125. "unable to get SLAPI_PLUGIN_IDENTITY\n" );
  126. return -1;
  127. }
  128. /* register the pre-operation search function, etc. */
  129. if ( slapi_pblock_set( pb, SLAPI_PLUGIN_VERSION, SLAPI_PLUGIN_VERSION_01
  130. ) != 0
  131. || slapi_pblock_set( pb, SLAPI_PLUGIN_DESCRIPTION,
  132. (void *)&plugindesc ) != 0
  133. || slapi_pblock_set( pb, SLAPI_PLUGIN_PRE_SEARCH_FN,
  134. (void *)nullsuffix_search ) != 0
  135. || slapi_pblock_set( pb, SLAPI_PLUGIN_CLOSE_FN,
  136. (void *)nullsuffix_close ) != 0
  137. || slapi_pblock_set( pb, SLAPI_PLUGIN_PRE_ADD_FN,
  138. (void *)nullsuffix_add) != 0
  139. || slapi_pblock_set( pb, SLAPI_PLUGIN_PRE_MODIFY_FN,
  140. (void *)nullsuffix_modify) != 0
  141. || slapi_pblock_set( pb, SLAPI_PLUGIN_PRE_DELETE_FN,
  142. (void *)nullsuffix_delete) != 0
  143. || slapi_pblock_set( pb, SLAPI_PLUGIN_PRE_BIND_FN,
  144. (void *)nullsuffix_bind) != 0
  145. || slapi_pblock_set( pb, SLAPI_PLUGIN_PRE_MODRDN_FN,
  146. (void *)nullsuffix_modrdn) != 0) {
  147. slapi_log_error( SLAPI_LOG_PLUGIN, PLUGIN_NAME,
  148. "failed to set version and function\n" );
  149. return -1;
  150. }
  151. return 0;
  152. }
  153. static int
  154. nullsuffix_bind( Slapi_PBlock *pb )
  155. {
  156. if( slapi_op_reserved(pb) ){
  157. return PLUGIN_OPERATION_IGNORED;
  158. }
  159. slapi_log_error( SLAPI_LOG_PLUGIN, PLUGIN_NAME, "nullsuffix_bind\n" );
  160. send_ldap_result( pb, LDAP_SUCCESS, NULL, NULL, 0, NULL );
  161. return PLUGIN_OPERATION_HANDLED;
  162. }
  163. static int
  164. nullsuffix_add( Slapi_PBlock *pb )
  165. {
  166. char *dn;
  167. if( slapi_op_reserved(pb) ){
  168. return PLUGIN_OPERATION_IGNORED;
  169. }
  170. slapi_log_error( SLAPI_LOG_PLUGIN, PLUGIN_NAME, "nullsuffix_add\n" );
  171. slapi_pblock_get( pb, SLAPI_ADD_TARGET, &dn );
  172. db_put_dn(dn);
  173. send_ldap_result( pb, LDAP_SUCCESS, NULL, NULL, 0, NULL );
  174. return PLUGIN_OPERATION_HANDLED;
  175. }
  176. static int
  177. nullsuffix_modify( Slapi_PBlock *pb )
  178. {
  179. Slapi_Entry *entry;
  180. int i;
  181. int j;
  182. char *dn;
  183. if( slapi_op_reserved(pb) ){
  184. return PLUGIN_OPERATION_IGNORED;
  185. }
  186. slapi_pblock_get( pb, SLAPI_MODIFY_TARGET, &dn );
  187. slapi_pblock_get( pb, SLAPI_ENTRY_PRE_OP, &entry);
  188. db_put_dn(dn);
  189. send_ldap_result( pb, LDAP_SUCCESS, NULL, NULL, 0, NULL );
  190. slapi_log_error( SLAPI_LOG_PLUGIN, PLUGIN_NAME, "nullsuffix_modify\n" );
  191. return PLUGIN_OPERATION_HANDLED;
  192. }
  193. static int
  194. nullsuffix_delete( Slapi_PBlock *pb )
  195. {
  196. if( slapi_op_reserved(pb) ){
  197. return PLUGIN_OPERATION_IGNORED;
  198. }
  199. slapi_log_error( SLAPI_LOG_PLUGIN, PLUGIN_NAME, "nullsuffix_delete\n" );
  200. send_ldap_result( pb, LDAP_SUCCESS, NULL, NULL, 0, NULL );
  201. return PLUGIN_OPERATION_HANDLED;
  202. }
  203. static int
  204. nullsuffix_modrdn( Slapi_PBlock *pb )
  205. {
  206. if( slapi_op_reserved(pb) ){
  207. return PLUGIN_OPERATION_IGNORED;
  208. }
  209. slapi_log_error( SLAPI_LOG_PLUGIN, PLUGIN_NAME, "nullsuffix_modrdn\n" );
  210. send_ldap_result( pb, LDAP_SUCCESS, NULL, NULL, 0, NULL );
  211. return PLUGIN_OPERATION_HANDLED;
  212. }
  213. static int
  214. nullsuffix_search( Slapi_PBlock *pb )
  215. {
  216. char *dn_base, **attrs, *newStr;
  217. int scope, sizelimit, timelimit, deref, attrsonly;
  218. Slapi_Filter *filter;
  219. Slapi_DN *sdn_base;
  220. int ldaperr = LDAP_SUCCESS; /* optimistic */
  221. int nentries = 0; /* entry count */
  222. int i;
  223. Slapi_Operation *op;
  224. Slapi_Entry *e;
  225. const char *entrystr =
  226. "dn:cn=Joe Smith,o=Example\n"
  227. "objectClass: top\n"
  228. "objectClass: person\n"
  229. "objectClass: organizationalPerson\n"
  230. "objectClass: inetOrgPerson\n"
  231. "cn:Joe Smith\n"
  232. "sn:Smith\n"
  233. "uid:jsmith\n"
  234. "mail:[email protected]\n";
  235. slapi_log_error( SLAPI_LOG_PLUGIN, PLUGIN_NAME, "nullsuffix_search\n" );
  236. if( slapi_op_reserved(pb) ){
  237. return PLUGIN_OPERATION_IGNORED;
  238. }
  239. /* get essential search parameters */
  240. if ( slapi_pblock_get( pb, SLAPI_SEARCH_TARGET, &dn_base ) != 0 ||
  241. slapi_pblock_get( pb, SLAPI_SEARCH_SCOPE, &scope ) != 0 ) {
  242. slapi_log_error( SLAPI_LOG_PLUGIN, PLUGIN_NAME,
  243. "could not get base DN and scope search parameters\n" );
  244. }
  245. if ( dn_base == NULL ) {
  246. dn_base = "";
  247. }
  248. sdn_base = slapi_sdn_new_dn_byval( dn_base );
  249. slapi_pblock_get(pb, SLAPI_OPERATION, &op);
  250. /* get remaining search parameters */
  251. if ( slapi_pblock_get( pb, SLAPI_SEARCH_DEREF, &deref ) != 0 ||
  252. slapi_pblock_get( pb, SLAPI_SEARCH_SIZELIMIT, &sizelimit ) != 0 ||
  253. slapi_pblock_get( pb, SLAPI_SEARCH_TIMELIMIT, &timelimit ) != 0 ||
  254. slapi_pblock_get( pb, SLAPI_SEARCH_FILTER, &filter ) != 0 ||
  255. slapi_pblock_get( pb, SLAPI_SEARCH_ATTRS, &attrs ) != 0 ||
  256. slapi_pblock_get( pb, SLAPI_SEARCH_ATTRSONLY, &attrsonly ) != 0 ) {
  257. slapi_log_error( SLAPI_LOG_PLUGIN, PLUGIN_NAME,
  258. "could not get remaining search parameters\n" );
  259. }
  260. if ( slapi_pblock_get( pb, SLAPI_OPERATION, &op ) != 0 ) {
  261. slapi_log_error( SLAPI_LOG_PLUGIN, PLUGIN_NAME,
  262. "could not get operation\n" );
  263. } else {
  264. slapi_operation_set_flag(op, SLAPI_OP_FLAG_NO_ACCESS_CHECK );
  265. }
  266. /* create a fake entry and send it along */
  267. newStr = slapi_ch_strdup( entrystr );
  268. if ( NULL == ( e = slapi_str2entry( newStr,
  269. SLAPI_STR2ENTRY_ADDRDNVALS
  270. | SLAPI_STR2ENTRY_EXPAND_OBJECTCLASSES ))) {
  271. slapi_log_error( SLAPI_LOG_PLUGIN, PLUGIN_NAME,
  272. "nullsuffix_search: slapi_str2entry() failed\n" );
  273. } else {
  274. slapi_send_ldap_search_entry( pb, e, NULL /* controls */,
  275. attrs, attrsonly );
  276. ++nentries;
  277. slapi_entry_free( e );
  278. }
  279. slapi_send_ldap_result( pb, ldaperr, NULL, "kilroy was here",
  280. nentries, NULL );
  281. slapi_log_error( SLAPI_LOG_PLUGIN, PLUGIN_NAME, "nullsuffix_search:"
  282. " handled search based at %s with scope %d; ldaperr=%d\n",
  283. dn_base, scope, ldaperr );
  284. slapi_ch_free_string(&newStr);
  285. slapi_sdn_free(&sdn_base);
  286. return PLUGIN_OPERATION_HANDLED;
  287. }
  288. /*
  289. * Shutdown function.
  290. */
  291. static int
  292. nullsuffix_close( Slapi_PBlock *pb )
  293. {
  294. slapi_log_error( SLAPI_LOG_PLUGIN, PLUGIN_NAME, "nullsuffix_close\n" );
  295. return 0;
  296. }