retrocl.c 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341
  1. /** BEGIN COPYRIGHT BLOCK
  2. * Copyright 2001 Sun Microsystems, Inc.
  3. * Portions copyright 1999, 2001-2003 Netscape Communications Corporation.
  4. * All rights reserved.
  5. * END COPYRIGHT BLOCK **/
  6. /*
  7. * Requires that create_instance.c have added a plugin entry similar to:
  8. dn: cn=Retrocl Plugin,cn=plugins,cn=config
  9. objectclass: top
  10. objectclass: nsSlapdPlugin
  11. objectclass: extensibleObject
  12. cn: RetroCL Plugin
  13. nsslapd-pluginpath: /export2/servers/Hydra-supplier/lib/retrocl-plugin.so
  14. nsslapd-plugininitfunc: retrocl_plugin_init
  15. nsslapd-plugintype: object
  16. nsslapd-pluginenabled: on
  17. nsslapd-plugin-depends-on-type: database
  18. nsslapd-pluginid: retrocl
  19. nsslapd-pluginversion: 5.0b2
  20. nsslapd-pluginvendor: Sun Microsystems, Inc.
  21. nsslapd-plugindescription: Retrocl Plugin
  22. *
  23. */
  24. #include "retrocl.h"
  25. #ifdef _WIN32
  26. int *module_ldap_debug = 0;
  27. void plugin_init_debug_level(int *level_ptr)
  28. {
  29. module_ldap_debug = level_ptr;
  30. }
  31. #endif
  32. void* g_plg_identity [PLUGIN_MAX];
  33. Slapi_Backend *retrocl_be_changelog = NULL;
  34. /* ----------------------------- Retrocl Plugin */
  35. static Slapi_PluginDesc retrocldesc = {"retrocl", PLUGIN_MAGIC_VENDOR_STR, PRODUCTTEXT, "Retrocl Plugin"};
  36. static Slapi_PluginDesc retroclpostopdesc = {"retrocl-postop", PLUGIN_MAGIC_VENDOR_STR, PRODUCTTEXT, "retrocl post-operation plugin"};
  37. static Slapi_PluginDesc retroclinternalpostopdesc = {"retrocl-internalpostop", PLUGIN_MAGIC_VENDOR_STR, PRODUCTTEXT, "retrocl internal post-operation plugin"};
  38. static Slapi_PluginDesc retroclbepostopdesc = {"retrocl-bepostop", PLUGIN_MAGIC_VENDOR_STR, PRODUCTTEXT, "Retrocl bepost-operation plugin"};
  39. /*
  40. * Function: retrocl_*
  41. *
  42. * Returns: LDAP_
  43. *
  44. * Arguments: Pb of operation
  45. *
  46. * Description: wrappers around retrocl_postob registered as callback
  47. *
  48. */
  49. int retrocl_postop_add (Slapi_PBlock *pb) { return retrocl_postob(pb,OP_ADD);}
  50. int retrocl_postop_delete (Slapi_PBlock *pb) { return retrocl_postob(pb,OP_DELETE);}
  51. int retrocl_postop_modify (Slapi_PBlock *pb) { return retrocl_postob(pb,OP_MODIFY);}
  52. int retrocl_postop_modrdn (Slapi_PBlock *pb) { return retrocl_postob(pb,OP_MODRDN);}
  53. /*
  54. * Function: retrocl_postop_init
  55. *
  56. * Returns: 0/-1
  57. *
  58. * Arguments: Pb
  59. *
  60. * Description: callback function
  61. *
  62. */
  63. int
  64. retrocl_postop_init( Slapi_PBlock *pb )
  65. {
  66. int rc= 0; /* OK */
  67. if( slapi_pblock_set( pb, SLAPI_PLUGIN_VERSION, SLAPI_PLUGIN_VERSION_01 ) != 0 ||
  68. slapi_pblock_set( pb, SLAPI_PLUGIN_DESCRIPTION, (void *)&retroclpostopdesc ) != 0 ||
  69. slapi_pblock_set( pb, SLAPI_PLUGIN_POST_ADD_FN, (void *) retrocl_postop_add ) != 0 ||
  70. slapi_pblock_set( pb, SLAPI_PLUGIN_POST_DELETE_FN, (void *) retrocl_postop_delete ) != 0 ||
  71. slapi_pblock_set( pb, SLAPI_PLUGIN_POST_MODIFY_FN, (void *) retrocl_postop_modify ) != 0 ||
  72. slapi_pblock_set( pb, SLAPI_PLUGIN_POST_MODRDN_FN, (void *) retrocl_postop_modrdn ) != 0 )
  73. {
  74. slapi_log_error( SLAPI_LOG_PLUGIN, RETROCL_PLUGIN_NAME, "retrocl_postop_init failed\n" );
  75. rc= -1;
  76. }
  77. return rc;
  78. }
  79. /*
  80. * Function: retrocl_internalpostop_init
  81. *
  82. * Returns: 0/-1
  83. *
  84. * Arguments: Pb
  85. *
  86. * Description: callback function
  87. *
  88. */
  89. int
  90. retrocl_internalpostop_init( Slapi_PBlock *pb )
  91. {
  92. int rc= 0; /* OK */
  93. if( slapi_pblock_set( pb, SLAPI_PLUGIN_VERSION, SLAPI_PLUGIN_VERSION_01 ) != 0 ||
  94. slapi_pblock_set( pb, SLAPI_PLUGIN_DESCRIPTION, (void *)&retroclinternalpostopdesc ) != 0 ||
  95. slapi_pblock_set( pb, SLAPI_PLUGIN_INTERNAL_POST_ADD_FN, (void *) retrocl_postop_add ) != 0 ||
  96. slapi_pblock_set( pb, SLAPI_PLUGIN_INTERNAL_POST_DELETE_FN, (void *) retrocl_postop_delete ) != 0 ||
  97. slapi_pblock_set( pb, SLAPI_PLUGIN_INTERNAL_POST_MODIFY_FN, (void *) retrocl_postop_modify ) != 0 ||
  98. slapi_pblock_set( pb, SLAPI_PLUGIN_INTERNAL_POST_MODRDN_FN, (void *) retrocl_postop_modrdn ) != 0 )
  99. {
  100. slapi_log_error( SLAPI_LOG_PLUGIN, RETROCL_PLUGIN_NAME, "retrocl_internalpostop_init failed\n" );
  101. rc= -1;
  102. }
  103. return rc;
  104. }
  105. /*
  106. * Function: retrocl_rootdse_init
  107. *
  108. * Returns: LDAP_SUCCESS
  109. *
  110. * Arguments: none
  111. *
  112. * Description: The FE DSE *must* be initialised before we get here.
  113. *
  114. */
  115. static int retrocl_rootdse_init(void)
  116. {
  117. int return_value= LDAP_SUCCESS;
  118. slapi_config_register_callback(SLAPI_OPERATION_SEARCH,DSE_FLAG_PREOP,"",
  119. LDAP_SCOPE_BASE,"(objectclass=*)",
  120. retrocl_rootdse_search,NULL);
  121. return return_value;
  122. }
  123. /*
  124. * Function: retrocl_select_backend
  125. *
  126. * Returns: LDAP_
  127. *
  128. * Arguments: none
  129. *
  130. * Description: simulates an add of the changelog to see if it exists. If not,
  131. * creates it. Then reads the changenumbers. This function should be called
  132. * exactly once at startup.
  133. *
  134. */
  135. static int retrocl_select_backend(void)
  136. {
  137. int err;
  138. Slapi_PBlock *pb;
  139. Slapi_Backend *be = NULL;
  140. Slapi_Entry *referral = NULL;
  141. Slapi_Operation *op = NULL;
  142. char errbuf[1024];
  143. pb = slapi_pblock_new();
  144. slapi_pblock_set (pb, SLAPI_PLUGIN_IDENTITY, g_plg_identity[PLUGIN_RETROCL]);
  145. /* This is a simulated operation; no actual add is performed */
  146. op = operation_new(OP_FLAG_INTERNAL);
  147. operation_set_type(op,SLAPI_OPERATION_ADD); /* Ensure be not readonly */
  148. operation_set_target_spec_str(op,RETROCL_CHANGELOG_DN);
  149. slapi_pblock_set(pb,SLAPI_OPERATION, op);
  150. err = slapi_mapping_tree_select(pb,&be,&referral,errbuf);
  151. slapi_entry_free(referral);
  152. operation_free(&op,NULL);
  153. if (err != LDAP_SUCCESS || be == NULL || be == defbackend_get_backend()) {
  154. LDAPDebug(LDAP_DEBUG_TRACE,"Mapping tree select failed (%d) %s.\n",
  155. err,errbuf,0);
  156. /* could not find the backend for cn=changelog, either because
  157. * it doesn't exist
  158. * mapping tree not registered.
  159. */
  160. err = retrocl_create_config();
  161. if (err != LDAP_SUCCESS) return err;
  162. } else {
  163. retrocl_be_changelog = be;
  164. }
  165. retrocl_create_cle();
  166. return retrocl_get_changenumbers();
  167. }
  168. /*
  169. * Function: retrocl_get_config_str
  170. *
  171. * Returns: malloc'ed string which must be freed.
  172. *
  173. * Arguments: attribute type name
  174. *
  175. * Description: reads a single-valued string attr from the plugins' own DSE.
  176. * This is called twice: to obtain the trim max age during startup, and to
  177. * obtain the change log directory. No callback is registered; you cannot
  178. * change the trim max age without restarting the server.
  179. *
  180. */
  181. char *retrocl_get_config_str(const char *attrt)
  182. {
  183. Slapi_Entry **entries;
  184. Slapi_PBlock *pb = NULL;
  185. char *ma;
  186. int rc = 0;
  187. char *dn;
  188. dn = RETROCL_PLUGIN_DN;
  189. pb = slapi_pblock_new();
  190. slapi_search_internal_set_pb (pb, dn, LDAP_SCOPE_BASE, "objectclass=*", NULL, 0, NULL,
  191. NULL, g_plg_identity[PLUGIN_RETROCL] , 0);
  192. slapi_search_internal_pb (pb);
  193. slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_RESULT, &rc);
  194. if (rc != 0) {
  195. slapi_pblock_destroy(pb);
  196. return NULL;
  197. }
  198. slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, &entries);
  199. ma = slapi_entry_attr_get_charptr(entries[0],attrt);
  200. slapi_free_search_results_internal(pb);
  201. slapi_pblock_destroy(pb);
  202. return ma;
  203. }
  204. /*
  205. * Function: retrocl_start
  206. *
  207. * Returns: 0 on success
  208. *
  209. * Arguments: Pb
  210. *
  211. * Description:
  212. *
  213. */
  214. static int retrocl_start (Slapi_PBlock *pb)
  215. {
  216. static int retrocl_started = 0;
  217. int rc = 0;
  218. if (!retrocl_started) {
  219. retrocl_rootdse_init();
  220. rc = retrocl_select_backend();
  221. if (rc == 0) {
  222. retrocl_init_trimming();
  223. } else {
  224. LDAPDebug(LDAP_DEBUG_TRACE,"Couldnt find backend, not trimming retro changelog (%d).\n",rc,0,0);
  225. }
  226. }
  227. retrocl_started = 1;
  228. return rc;
  229. }
  230. /*
  231. * Function: retrocl_stop
  232. *
  233. * Returns: 0
  234. *
  235. * Arguments: Pb
  236. *
  237. * Description: called when the server is shutting down
  238. *
  239. */
  240. static int retrocl_stop (Slapi_PBlock *pb)
  241. {
  242. int rc = 0;
  243. retrocl_stop_trimming();
  244. retrocl_be_changelog = NULL;
  245. retrocl_forget_changenumbers();
  246. return rc;
  247. }
  248. /*
  249. * Function: retrocl_plugin_init
  250. *
  251. * Returns: 0 on successs
  252. *
  253. * Arguments: Pb
  254. *
  255. * Description: main entry point for retrocl
  256. *
  257. */
  258. int
  259. retrocl_plugin_init(Slapi_PBlock *pb)
  260. {
  261. static int legacy_initialised= 0;
  262. int rc = 0;
  263. void *identity = NULL;
  264. slapi_pblock_get (pb, SLAPI_PLUGIN_IDENTITY, &identity);
  265. PR_ASSERT (identity);
  266. g_plg_identity[PLUGIN_RETROCL] = identity;
  267. if (!legacy_initialised) {
  268. rc= slapi_pblock_set( pb, SLAPI_PLUGIN_VERSION, SLAPI_PLUGIN_VERSION_01 );
  269. rc= slapi_pblock_set( pb, SLAPI_PLUGIN_DESCRIPTION, (void *)&retrocldesc );
  270. rc= slapi_pblock_set( pb, SLAPI_PLUGIN_START_FN, (void *) retrocl_start );
  271. rc= slapi_pblock_set( pb, SLAPI_PLUGIN_CLOSE_FN, (void *) retrocl_stop );
  272. rc= slapi_register_plugin("postoperation", 1 /* Enabled */, "retrocl_postop_init", retrocl_postop_init, "Retrocl postoperation plugin", NULL, identity);
  273. rc= slapi_register_plugin("internalpostoperation", 1 /* Enabled */, "retrocl_internalpostop_init", retrocl_internalpostop_init, "Retrocl internal postoperation plugin", NULL, identity);
  274. }
  275. legacy_initialised = 1;
  276. return rc;
  277. }