retrocl.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691
  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. *
  6. * License: GPL (version 3 or any later version).
  7. * See LICENSE for details.
  8. * END COPYRIGHT BLOCK **/
  9. #ifdef HAVE_CONFIG_H
  10. #include <config.h>
  11. #endif
  12. /*
  13. * Requires that create_instance.c have added a plugin entry similar to:
  14. dn: cn=Retrocl Plugin,cn=plugins,cn=config
  15. objectclass: top
  16. objectclass: nsSlapdPlugin
  17. objectclass: extensibleObject
  18. cn: RetroCL Plugin
  19. nsslapd-pluginpath: /export2/servers/Hydra-supplier/lib/retrocl-plugin.so
  20. nsslapd-plugininitfunc: retrocl_plugin_init
  21. nsslapd-plugintype: object
  22. nsslapd-pluginenabled: on
  23. nsslapd-plugin-depends-on-type: database
  24. nsslapd-pluginid: retrocl
  25. nsslapd-pluginversion: 5.0b2
  26. nsslapd-pluginvendor: Sun Microsystems, Inc.
  27. nsslapd-plugindescription: Retrocl Plugin
  28. *
  29. */
  30. #include "retrocl.h"
  31. void *g_plg_identity[PLUGIN_MAX];
  32. Slapi_Backend *retrocl_be_changelog = NULL;
  33. PRLock *retrocl_internal_lock = NULL;
  34. Slapi_RWLock *retrocl_cn_lock;
  35. int retrocl_nattributes = 0;
  36. char **retrocl_attributes = NULL;
  37. char **retrocl_aliases = NULL;
  38. int retrocl_log_deleted = 0;
  39. static Slapi_DN **retrocl_includes = NULL;
  40. static Slapi_DN **retrocl_excludes = NULL;
  41. /* ----------------------------- Retrocl Plugin */
  42. static Slapi_PluginDesc retrocldesc = {"retrocl", VENDOR, DS_PACKAGE_VERSION, "Retrocl Plugin"};
  43. static Slapi_PluginDesc retroclpostopdesc = {"retrocl-postop", VENDOR, DS_PACKAGE_VERSION, "retrocl post-operation plugin"};
  44. static Slapi_PluginDesc retroclinternalpostopdesc = {"retrocl-internalpostop", VENDOR, DS_PACKAGE_VERSION, "retrocl internal post-operation plugin"};
  45. static int legacy_initialised = 0;
  46. /*
  47. * Function: retrocl_*
  48. *
  49. * Returns: LDAP_
  50. *
  51. * Arguments: Pb of operation
  52. *
  53. * Description: wrappers around retrocl_postob registered as callback
  54. *
  55. */
  56. int
  57. retrocl_postop_add(Slapi_PBlock *pb)
  58. {
  59. return retrocl_postob(pb, OP_ADD);
  60. }
  61. int
  62. retrocl_postop_delete(Slapi_PBlock *pb)
  63. {
  64. return retrocl_postob(pb, OP_DELETE);
  65. }
  66. int
  67. retrocl_postop_modify(Slapi_PBlock *pb)
  68. {
  69. return retrocl_postob(pb, OP_MODIFY);
  70. }
  71. int
  72. retrocl_postop_modrdn(Slapi_PBlock *pb)
  73. {
  74. return retrocl_postob(pb, OP_MODRDN);
  75. }
  76. /*
  77. * Function: retrocl_postop_init
  78. *
  79. * Returns: 0/-1
  80. *
  81. * Arguments: Pb
  82. *
  83. * Description: callback function
  84. *
  85. */
  86. int
  87. retrocl_postop_init(Slapi_PBlock *pb)
  88. {
  89. int rc = 0; /* OK */
  90. Slapi_Entry *plugin_entry = NULL;
  91. char *plugin_type = NULL;
  92. int postadd = SLAPI_PLUGIN_POST_ADD_FN;
  93. int postmod = SLAPI_PLUGIN_POST_MODIFY_FN;
  94. int postmdn = SLAPI_PLUGIN_POST_MODRDN_FN;
  95. int postdel = SLAPI_PLUGIN_POST_DELETE_FN;
  96. if ((slapi_pblock_get(pb, SLAPI_PLUGIN_CONFIG_ENTRY, &plugin_entry) == 0) &&
  97. plugin_entry &&
  98. (plugin_type = slapi_entry_attr_get_charptr(plugin_entry, "nsslapd-plugintype")) &&
  99. plugin_type && strstr(plugin_type, "betxn")) {
  100. postadd = SLAPI_PLUGIN_BE_TXN_POST_ADD_FN;
  101. postmod = SLAPI_PLUGIN_BE_TXN_POST_MODIFY_FN;
  102. postmdn = SLAPI_PLUGIN_BE_TXN_POST_MODRDN_FN;
  103. postdel = SLAPI_PLUGIN_BE_TXN_POST_DELETE_FN;
  104. }
  105. slapi_ch_free_string(&plugin_type);
  106. if (slapi_pblock_set(pb, SLAPI_PLUGIN_VERSION, SLAPI_PLUGIN_VERSION_01) != 0 ||
  107. slapi_pblock_set(pb, SLAPI_PLUGIN_DESCRIPTION, (void *)&retroclpostopdesc) != 0 ||
  108. slapi_pblock_set(pb, postadd, (void *)retrocl_postop_add) != 0 ||
  109. slapi_pblock_set(pb, postdel, (void *)retrocl_postop_delete) != 0 ||
  110. slapi_pblock_set(pb, postmod, (void *)retrocl_postop_modify) != 0 ||
  111. slapi_pblock_set(pb, postmdn, (void *)retrocl_postop_modrdn) != 0) {
  112. slapi_log_err(SLAPI_LOG_PLUGIN, RETROCL_PLUGIN_NAME, "retrocl_postop_init failed\n");
  113. rc = -1;
  114. }
  115. return rc;
  116. }
  117. /*
  118. * Function: retrocl_internalpostop_init
  119. *
  120. * Returns: 0/-1
  121. *
  122. * Arguments: Pb
  123. *
  124. * Description: callback function
  125. *
  126. */
  127. int
  128. retrocl_internalpostop_init(Slapi_PBlock *pb)
  129. {
  130. int rc = 0; /* OK */
  131. if (slapi_pblock_set(pb, SLAPI_PLUGIN_VERSION, SLAPI_PLUGIN_VERSION_01) != 0 ||
  132. slapi_pblock_set(pb, SLAPI_PLUGIN_DESCRIPTION, (void *)&retroclinternalpostopdesc) != 0 ||
  133. slapi_pblock_set(pb, SLAPI_PLUGIN_INTERNAL_POST_ADD_FN, (void *)retrocl_postop_add) != 0 ||
  134. slapi_pblock_set(pb, SLAPI_PLUGIN_INTERNAL_POST_DELETE_FN, (void *)retrocl_postop_delete) != 0 ||
  135. slapi_pblock_set(pb, SLAPI_PLUGIN_INTERNAL_POST_MODIFY_FN, (void *)retrocl_postop_modify) != 0 ||
  136. slapi_pblock_set(pb, SLAPI_PLUGIN_INTERNAL_POST_MODRDN_FN, (void *)retrocl_postop_modrdn) != 0) {
  137. slapi_log_err(SLAPI_LOG_PLUGIN, RETROCL_PLUGIN_NAME, "retrocl_internalpostop_init failed\n");
  138. rc = -1;
  139. }
  140. return rc;
  141. }
  142. /*
  143. * Function: retrocl_rootdse_init
  144. *
  145. * Returns: LDAP_SUCCESS
  146. *
  147. * Arguments: Slapi_PBlock
  148. *
  149. * Description: The FE DSE *must* be initialised before we get here.
  150. *
  151. */
  152. static int
  153. retrocl_rootdse_init(Slapi_PBlock *pb)
  154. {
  155. int return_value = LDAP_SUCCESS;
  156. slapi_config_register_callback_plugin(SLAPI_OPERATION_SEARCH, DSE_FLAG_PREOP | DSE_FLAG_PLUGIN, "",
  157. LDAP_SCOPE_BASE, "(objectclass=*)",
  158. retrocl_rootdse_search, NULL, pb);
  159. return return_value;
  160. }
  161. /*
  162. * Function: retrocl_select_backend
  163. *
  164. * Returns: LDAP_
  165. *
  166. * Arguments: none
  167. *
  168. * Description: simulates an add of the changelog to see if it exists. If not,
  169. * creates it. Then reads the changenumbers. This function should be called
  170. * exactly once at startup.
  171. *
  172. */
  173. static int
  174. retrocl_select_backend(void)
  175. {
  176. int err;
  177. Slapi_PBlock *pb;
  178. Slapi_Backend *be = NULL;
  179. Slapi_Entry *referral = NULL;
  180. Slapi_Operation *op = NULL;
  181. char errbuf[SLAPI_DSE_RETURNTEXT_SIZE];
  182. pb = slapi_pblock_new();
  183. slapi_pblock_set(pb, SLAPI_PLUGIN_IDENTITY, g_plg_identity[PLUGIN_RETROCL]);
  184. /* This is a simulated operation; no actual add is performed */
  185. op = operation_new(OP_FLAG_INTERNAL);
  186. operation_set_type(op, SLAPI_OPERATION_ADD); /* Ensure be not readonly */
  187. operation_set_target_spec_str(op, RETROCL_CHANGELOG_DN);
  188. slapi_pblock_set(pb, SLAPI_OPERATION, op);
  189. err = slapi_mapping_tree_select(pb, &be, &referral, errbuf, sizeof(errbuf));
  190. slapi_entry_free(referral);
  191. if (err != LDAP_SUCCESS || be == NULL || be == defbackend_get_backend()) {
  192. slapi_log_err(SLAPI_LOG_ERR, RETROCL_PLUGIN_NAME,
  193. "retrocl_select_backend - Mapping tree select failed (%d) %s.\n", err, errbuf);
  194. /* could not find the backend for cn=changelog, either because
  195. * it doesn't exist
  196. * mapping tree not registered.
  197. */
  198. err = retrocl_create_config();
  199. if (err != LDAP_SUCCESS)
  200. return err;
  201. } else {
  202. retrocl_be_changelog = be;
  203. }
  204. retrocl_create_cle();
  205. slapi_pblock_destroy(pb);
  206. if (be)
  207. slapi_be_Unlock(be);
  208. return retrocl_get_changenumbers();
  209. }
  210. /*
  211. * Function: retrocl_get_config_str
  212. *
  213. * Returns: malloc'ed string which must be freed.
  214. *
  215. * Arguments: attribute type name
  216. *
  217. * Description: reads a single-valued string attr from the plugins' own DSE.
  218. * This is called twice: to obtain the trim max age during startup, and to
  219. * obtain the change log directory. No callback is registered; you cannot
  220. * change the trim max age without restarting the server.
  221. *
  222. */
  223. char *
  224. retrocl_get_config_str(const char *attrt)
  225. {
  226. Slapi_Entry **entries;
  227. Slapi_PBlock *pb = NULL;
  228. char *ma;
  229. int rc = 0;
  230. char *dn;
  231. /* RETROCL_PLUGIN_DN is no need to be normalized. */
  232. dn = RETROCL_PLUGIN_DN;
  233. pb = slapi_pblock_new();
  234. slapi_search_internal_set_pb(pb, dn, LDAP_SCOPE_BASE, "objectclass=*", NULL, 0, NULL,
  235. NULL, g_plg_identity[PLUGIN_RETROCL], 0);
  236. slapi_search_internal_pb(pb);
  237. slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_RESULT, &rc);
  238. if (rc != 0) {
  239. slapi_pblock_destroy(pb);
  240. return NULL;
  241. }
  242. slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, &entries);
  243. ma = slapi_entry_attr_get_charptr(entries[0], attrt);
  244. slapi_free_search_results_internal(pb);
  245. slapi_pblock_destroy(pb);
  246. return ma;
  247. }
  248. static void
  249. retrocl_remove_legacy_default_aci(void)
  250. {
  251. Slapi_PBlock *pb = NULL;
  252. Slapi_Entry **entries;
  253. char **aci_vals = NULL;
  254. char *attrs[] = {"aci", NULL};
  255. int rc;
  256. pb = slapi_pblock_new();
  257. slapi_search_internal_set_pb(pb, RETROCL_CHANGELOG_DN, LDAP_SCOPE_BASE, "objectclass=*",
  258. attrs, 0, NULL, NULL, g_plg_identity[PLUGIN_RETROCL], 0);
  259. slapi_search_internal_pb(pb);
  260. slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_RESULT, &rc);
  261. if (rc == LDAP_SUCCESS) {
  262. slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, &entries);
  263. if (entries && entries[0]) {
  264. if ((aci_vals = slapi_entry_attr_get_charray(entries[0], "aci"))) {
  265. if (charray_inlist(aci_vals, RETROCL_ACL)) {
  266. /*
  267. * Okay, we need to remove the aci
  268. */
  269. LDAPMod mod;
  270. LDAPMod *mods[2];
  271. char *val[2];
  272. Slapi_PBlock *mod_pb = 0;
  273. mod_pb = slapi_pblock_new();
  274. mods[0] = &mod;
  275. mods[1] = 0;
  276. val[0] = RETROCL_ACL;
  277. val[1] = 0;
  278. mod.mod_op = LDAP_MOD_DELETE;
  279. mod.mod_type = "aci";
  280. mod.mod_values = val;
  281. slapi_modify_internal_set_pb_ext(mod_pb, slapi_entry_get_sdn(entries[0]),
  282. mods, 0, 0, g_plg_identity[PLUGIN_RETROCL], 0);
  283. slapi_modify_internal_pb(mod_pb);
  284. slapi_pblock_get(mod_pb, SLAPI_PLUGIN_INTOP_RESULT, &rc);
  285. if (rc == LDAP_SUCCESS) {
  286. slapi_log_err(SLAPI_LOG_NOTICE, RETROCL_PLUGIN_NAME,
  287. "retrocl_remove_legacy_default_aci - "
  288. "Successfully removed vulnerable legacy default aci \"%s\". "
  289. "If the aci removal was not desired please use a different \"acl "
  290. "name\" so it is not removed at the next plugin startup.\n",
  291. RETROCL_ACL);
  292. } else {
  293. slapi_log_err(SLAPI_LOG_ERR, RETROCL_PLUGIN_NAME,
  294. "retrocl_remove_legacy_default_aci - "
  295. "Failed to removed vulnerable legacy default aci (%s) error %d\n",
  296. RETROCL_ACL, rc);
  297. }
  298. slapi_pblock_destroy(mod_pb);
  299. }
  300. slapi_ch_array_free(aci_vals);
  301. }
  302. }
  303. }
  304. slapi_free_search_results_internal(pb);
  305. slapi_pblock_destroy(pb);
  306. }
  307. /*
  308. * Function: retrocl_start
  309. *
  310. * Returns: 0 on success
  311. *
  312. * Arguments: Pb
  313. *
  314. * Description:
  315. *
  316. */
  317. static int
  318. retrocl_start(Slapi_PBlock *pb)
  319. {
  320. int rc = 0;
  321. Slapi_Entry *e = NULL;
  322. char **values = NULL;
  323. int num_vals = 0;
  324. int i = 0;
  325. retrocl_rootdse_init(pb);
  326. rc = retrocl_select_backend();
  327. if (rc != 0) {
  328. slapi_log_err(SLAPI_LOG_TRACE, RETROCL_PLUGIN_NAME, "retrocl_start - Couldn't find backend, not trimming retro changelog (%d).\n", rc);
  329. return rc;
  330. }
  331. /* Remove the old default aci as it exposes passwords changes to anonymous users */
  332. retrocl_remove_legacy_default_aci();
  333. retrocl_init_trimming();
  334. if (slapi_pblock_get(pb, SLAPI_ADD_ENTRY, &e) != 0) {
  335. slapi_log_err(SLAPI_LOG_ERR, RETROCL_PLUGIN_NAME, "retrocl_start - Missing config entry.\n");
  336. return -1;
  337. }
  338. /* Get the exclude suffixes */
  339. values = slapi_entry_attr_get_charray_ext(e, CONFIG_CHANGELOG_EXCLUDE_SUFFIX, &num_vals);
  340. if (values) {
  341. /* Validate the syntax before we create our DN array */
  342. for (i = 0; i < num_vals; i++) {
  343. if (slapi_dn_syntax_check(pb, values[i], 1)) {
  344. /* invalid dn syntax */
  345. slapi_log_err(SLAPI_LOG_ERR, RETROCL_PLUGIN_NAME,
  346. "retrocl_start - Invalid DN (%s) for exclude suffix.\n", values[i]);
  347. slapi_ch_array_free(values);
  348. return -1;
  349. }
  350. }
  351. /* Now create our SDN array */
  352. retrocl_excludes = (Slapi_DN **)slapi_ch_calloc(sizeof(Slapi_DN *), num_vals + 1);
  353. for (i = 0; i < num_vals; i++) {
  354. retrocl_excludes[i] = slapi_sdn_new_dn_byval(values[i]);
  355. }
  356. slapi_ch_array_free(values);
  357. }
  358. /* Get the include suffixes */
  359. values = slapi_entry_attr_get_charray_ext(e, CONFIG_CHANGELOG_INCLUDE_SUFFIX, &num_vals);
  360. if (values) {
  361. for (i = 0; i < num_vals; i++) {
  362. /* Validate the syntax before we create our DN array */
  363. if (slapi_dn_syntax_check(pb, values[i], 1)) {
  364. /* invalid dn syntax */
  365. slapi_log_err(SLAPI_LOG_ERR, RETROCL_PLUGIN_NAME,
  366. "retrocl_start - Invalid DN (%s) for include suffix.\n", values[i]);
  367. slapi_ch_array_free(values);
  368. return -1;
  369. }
  370. }
  371. /* Now create our SDN array */
  372. retrocl_includes = (Slapi_DN **)slapi_ch_calloc(sizeof(Slapi_DN *), num_vals + 1);
  373. for (i = 0; i < num_vals; i++) {
  374. retrocl_includes[i] = slapi_sdn_new_dn_byval(values[i]);
  375. }
  376. slapi_ch_array_free(values);
  377. }
  378. if (retrocl_includes && retrocl_excludes) {
  379. /*
  380. * Make sure we haven't mixed the same suffix, and there are no
  381. * conflicts between the includes and excludes
  382. */
  383. int i = 0;
  384. while (retrocl_includes[i]) {
  385. int x = 0;
  386. while (retrocl_excludes[x]) {
  387. if (slapi_sdn_compare(retrocl_includes[i], retrocl_excludes[x]) == 0) {
  388. /* we have a conflict */
  389. slapi_log_err(SLAPI_LOG_ERR, RETROCL_PLUGIN_NAME,
  390. "retrocl_start - Include suffix (%s) is also listed in exclude suffix list\n",
  391. slapi_sdn_get_dn(retrocl_includes[i]));
  392. return -1;
  393. }
  394. x++;
  395. }
  396. i++;
  397. }
  398. /* Check for parent/child conflicts */
  399. i = 0;
  400. while (retrocl_includes[i]) {
  401. int x = 0;
  402. while (retrocl_excludes[x]) {
  403. if (slapi_sdn_issuffix(retrocl_includes[i], retrocl_excludes[x])) {
  404. /* we have a conflict */
  405. slapi_log_err(SLAPI_LOG_ERR, RETROCL_PLUGIN_NAME,
  406. "retrocl_start - include suffix (%s) is a child of the exclude suffix(%s)\n",
  407. slapi_sdn_get_dn(retrocl_includes[i]),
  408. slapi_sdn_get_dn(retrocl_excludes[i]));
  409. return -1;
  410. }
  411. x++;
  412. }
  413. i++;
  414. }
  415. }
  416. values = slapi_entry_attr_get_charray(e, "nsslapd-attribute");
  417. if (values != NULL) {
  418. int n = 0;
  419. int i = 0;
  420. slapi_log_err(SLAPI_LOG_PLUGIN, RETROCL_PLUGIN_NAME, "retrocl_start - nsslapd-attribute:\n");
  421. for (n = 0; values && values[n]; n++) {
  422. slapi_log_err(SLAPI_LOG_PLUGIN, RETROCL_PLUGIN_NAME, "retrocl_start - %s\n", values[n]);
  423. }
  424. retrocl_nattributes = n;
  425. retrocl_attributes = (char **)slapi_ch_calloc(n + 1, sizeof(char *));
  426. retrocl_aliases = (char **)slapi_ch_calloc(n + 1, sizeof(char *));
  427. slapi_log_err(SLAPI_LOG_PLUGIN, RETROCL_PLUGIN_NAME, "retrocl_start - Attributes:\n");
  428. for (i = 0; i < n; i++) {
  429. char *value = values[i];
  430. size_t length = strlen(value);
  431. char *pos = strchr(value, ':');
  432. if (pos == NULL) {
  433. retrocl_attributes[i] = slapi_ch_strdup(value);
  434. retrocl_aliases[i] = NULL;
  435. slapi_log_err(SLAPI_LOG_PLUGIN, RETROCL_PLUGIN_NAME, " - %s\n",
  436. retrocl_attributes[i]);
  437. } else {
  438. retrocl_attributes[i] = slapi_ch_malloc(pos - value + 1);
  439. strncpy(retrocl_attributes[i], value, pos - value);
  440. retrocl_attributes[i][pos - value] = '\0';
  441. retrocl_aliases[i] = slapi_ch_malloc(value + length - pos);
  442. strcpy(retrocl_aliases[i], pos + 1);
  443. slapi_log_err(SLAPI_LOG_PLUGIN, RETROCL_PLUGIN_NAME, " - %s [%s]\n",
  444. retrocl_attributes[i], retrocl_aliases[i]);
  445. }
  446. }
  447. slapi_ch_array_free(values);
  448. }
  449. retrocl_log_deleted = 0;
  450. values = slapi_entry_attr_get_charray(e, "nsslapd-log-deleted");
  451. if (values != NULL) {
  452. if (values[1] != NULL) {
  453. slapi_log_err(SLAPI_LOG_PLUGIN, RETROCL_PLUGIN_NAME,
  454. "retrocl_start - Multiple values specified for attribute: nsslapd-log-deleted\n");
  455. } else if (0 == strcasecmp(values[0], "on")) {
  456. retrocl_log_deleted = 1;
  457. } else if (strcasecmp(values[0], "off")) {
  458. slapi_log_err(SLAPI_LOG_PLUGIN, RETROCL_PLUGIN_NAME,
  459. "Iretrocl_start - nvalid value (%s) specified for attribute: nsslapd-log-deleted\n", values[0]);
  460. }
  461. slapi_ch_array_free(values);
  462. }
  463. return 0;
  464. }
  465. /*
  466. * Check if an entry is in the configured scope.
  467. * Return 1 if entry is in the scope, or 0 otherwise.
  468. * For MODRDN the caller should check both the preop
  469. * and postop entries. If we are moving out of, or
  470. * into scope, we should record it.
  471. */
  472. int
  473. retrocl_entry_in_scope(Slapi_Entry *e)
  474. {
  475. Slapi_DN *sdn = slapi_entry_get_sdn(e);
  476. if (e == NULL) {
  477. return 1;
  478. }
  479. if (retrocl_excludes) {
  480. int i = 0;
  481. /* check the excludes */
  482. while (retrocl_excludes[i]) {
  483. if (slapi_sdn_issuffix(sdn, retrocl_excludes[i])) {
  484. return 0;
  485. }
  486. i++;
  487. }
  488. }
  489. if (retrocl_includes) {
  490. int i = 0;
  491. /* check the excludes */
  492. while (retrocl_includes[i]) {
  493. if (slapi_sdn_issuffix(sdn, retrocl_includes[i])) {
  494. return 1;
  495. }
  496. i++;
  497. }
  498. return 0;
  499. }
  500. return 1;
  501. }
  502. /*
  503. * Function: retrocl_stop
  504. *
  505. * Returns: 0
  506. *
  507. * Arguments: Pb
  508. *
  509. * Description: called when the server is shutting down
  510. *
  511. */
  512. static int
  513. retrocl_stop(Slapi_PBlock *pb __attribute__((unused)))
  514. {
  515. int rc = 0;
  516. int i = 0;
  517. slapi_ch_array_free(retrocl_attributes);
  518. retrocl_attributes = NULL;
  519. slapi_ch_array_free(retrocl_aliases);
  520. retrocl_aliases = NULL;
  521. while (retrocl_excludes && retrocl_excludes[i]) {
  522. slapi_sdn_free(&retrocl_excludes[i]);
  523. i++;
  524. }
  525. slapi_ch_free((void **)&retrocl_excludes);
  526. i = 0;
  527. while (retrocl_includes && retrocl_includes[i]) {
  528. slapi_sdn_free(&retrocl_includes[i]);
  529. i++;
  530. }
  531. slapi_ch_free((void **)&retrocl_includes);
  532. retrocl_stop_trimming();
  533. retrocl_be_changelog = NULL;
  534. retrocl_forget_changenumbers();
  535. PR_DestroyLock(retrocl_internal_lock);
  536. retrocl_internal_lock = NULL;
  537. slapi_destroy_rwlock(retrocl_cn_lock);
  538. retrocl_cn_lock = NULL;
  539. legacy_initialised = 0;
  540. slapi_config_remove_callback(SLAPI_OPERATION_SEARCH, DSE_FLAG_PREOP, "",
  541. LDAP_SCOPE_BASE, "(objectclass=*)", retrocl_rootdse_search);
  542. return rc;
  543. }
  544. /*
  545. * Function: retrocl_plugin_init
  546. *
  547. * Returns: 0 on successs
  548. *
  549. * Arguments: Pb
  550. *
  551. * Description: main entry point for retrocl
  552. *
  553. */
  554. int
  555. retrocl_plugin_init(Slapi_PBlock *pb)
  556. {
  557. int rc = 0;
  558. int precedence = 0;
  559. void *identity = NULL;
  560. Slapi_Entry *plugin_entry = NULL;
  561. int is_betxn = 0;
  562. const char *plugintype = "postoperation";
  563. slapi_pblock_get(pb, SLAPI_PLUGIN_IDENTITY, &identity);
  564. PR_ASSERT(identity);
  565. g_plg_identity[PLUGIN_RETROCL] = identity;
  566. slapi_pblock_get(pb, SLAPI_PLUGIN_PRECEDENCE, &precedence);
  567. if ((slapi_pblock_get(pb, SLAPI_PLUGIN_CONFIG_ENTRY, &plugin_entry) == 0) &&
  568. plugin_entry) {
  569. is_betxn = slapi_entry_attr_get_bool(plugin_entry, "nsslapd-pluginbetxn");
  570. }
  571. if (!legacy_initialised) {
  572. rc = slapi_pblock_set(pb, SLAPI_PLUGIN_VERSION, SLAPI_PLUGIN_VERSION_01);
  573. rc = slapi_pblock_set(pb, SLAPI_PLUGIN_DESCRIPTION, (void *)&retrocldesc);
  574. rc = slapi_pblock_set(pb, SLAPI_PLUGIN_START_FN, (void *)retrocl_start);
  575. rc = slapi_pblock_set(pb, SLAPI_PLUGIN_CLOSE_FN, (void *)retrocl_stop);
  576. if (is_betxn) {
  577. plugintype = "betxnpostoperation";
  578. }
  579. rc = slapi_register_plugin_ext(plugintype, 1 /* Enabled */, "retrocl_postop_init", retrocl_postop_init, "Retrocl postoperation plugin", NULL, identity, precedence);
  580. if (!is_betxn) {
  581. rc = slapi_register_plugin_ext("internalpostoperation", 1 /* Enabled */, "retrocl_internalpostop_init", retrocl_internalpostop_init, "Retrocl internal postoperation plugin", NULL, identity, precedence);
  582. }
  583. retrocl_cn_lock = slapi_new_rwlock();
  584. if (retrocl_cn_lock == NULL)
  585. return -1;
  586. retrocl_internal_lock = PR_NewLock();
  587. if (retrocl_internal_lock == NULL)
  588. return -1;
  589. }
  590. legacy_initialised = 1;
  591. return rc;
  592. }