retrocl.c 8.6 KB

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