cb_config.c 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632
  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. #include "cb.h"
  39. #include <errno.h>
  40. /* Forward declarations */
  41. static int cb_parse_config_entry(cb_backend * cb, Slapi_Entry *e);
  42. /* body starts here */
  43. /* Used to add an array of entries, like the one above and
  44. ** cb_instance_skeleton_entries to the dse.
  45. ** Returns 0 on success.
  46. */
  47. int cb_config_add_dse_entries(cb_backend *cb, char **entries, char *string1, char *string2, char *string3)
  48. {
  49. int x;
  50. Slapi_Entry *e;
  51. Slapi_PBlock *util_pb = NULL;
  52. int res, rc = 0;
  53. char entry_string[CB_BUFSIZE];
  54. for(x = 0; strlen(entries[x]) > 0; x++) {
  55. util_pb = slapi_pblock_new();
  56. PR_snprintf(entry_string, sizeof(entry_string), entries[x], string1, string2, string3);
  57. e = slapi_str2entry(entry_string, 0);
  58. slapi_add_entry_internal_set_pb(util_pb, e, NULL, cb->identity, 0);
  59. slapi_add_internal_pb(util_pb);
  60. slapi_pblock_get(util_pb, SLAPI_PLUGIN_INTOP_RESULT, &res);
  61. if ( LDAP_SUCCESS != res && LDAP_ALREADY_EXISTS != res ) {
  62. char ebuf[ BUFSIZ ];
  63. slapi_log_error(SLAPI_LOG_PLUGIN, CB_PLUGIN_SUBSYSTEM,
  64. "Unable to add config entry (%s) to the DSE: %s\n",
  65. escape_string(slapi_entry_get_dn(e), ebuf),
  66. ldap_err2string(res));
  67. rc = res;
  68. slapi_pblock_destroy(util_pb);
  69. break;
  70. }
  71. slapi_pblock_destroy(util_pb);
  72. }
  73. return rc;
  74. }
  75. /*
  76. ** Try to read the entry cn=config,cn=chaining database,cn=plugins,cn=config
  77. ** If the entry is there, then process the configuration information it stores.
  78. ** If it is missing, create it with default configuration.
  79. ** The default configuration is taken from the default entry if it exists
  80. */
  81. int cb_config_load_dse_info(Slapi_PBlock * pb) {
  82. Slapi_PBlock *search_pb,*default_pb;
  83. Slapi_Entry **entries = NULL;
  84. Slapi_Entry *configEntry=NULL;
  85. int res,default_res,i;
  86. char defaultDn[CB_BUFSIZE];
  87. cb_backend *cb;
  88. slapi_pblock_get( pb, SLAPI_PLUGIN_PRIVATE, &cb );
  89. /* Get global configuration entry */
  90. search_pb = slapi_pblock_new();
  91. slapi_search_internal_set_pb(search_pb, cb->configDN, LDAP_SCOPE_BASE,
  92. "objectclass=*", NULL, 0, NULL, NULL, cb->identity, 0);
  93. slapi_search_internal_pb (search_pb);
  94. slapi_pblock_get(search_pb, SLAPI_PLUGIN_INTOP_RESULT, &res);
  95. if ( LDAP_SUCCESS == res ) {
  96. slapi_pblock_get(search_pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, &entries);
  97. if (NULL == entries || entries[0] == NULL) {
  98. slapi_log_error(SLAPI_LOG_PLUGIN, CB_PLUGIN_SUBSYSTEM,
  99. "Error accessing entry <%s>\n",cb->configDN);
  100. slapi_free_search_results_internal(search_pb);
  101. slapi_pblock_destroy(search_pb);
  102. return 1;
  103. }
  104. configEntry=entries[0];
  105. } else
  106. if ( LDAP_NO_SUCH_OBJECT == res ) {
  107. /* Don't do anything. The default conf is used */
  108. configEntry=NULL;
  109. } else {
  110. slapi_free_search_results_internal(search_pb);
  111. slapi_pblock_destroy(search_pb);
  112. slapi_log_error(SLAPI_LOG_PLUGIN, CB_PLUGIN_SUBSYSTEM,
  113. "Error accessing entry <%s> (%s)\n",cb->configDN,ldap_err2string(res));
  114. return 1;
  115. }
  116. /* Parse the configuration entry */
  117. /* Default config if configEntry is NULL*/
  118. cb_parse_config_entry(cb, configEntry);
  119. slapi_free_search_results_internal(search_pb);
  120. slapi_pblock_destroy(search_pb);
  121. /*
  122. ** Parse the chaining backend instances
  123. ** Immediate subordinates of cn=<plugin name>,cn=plugins,cn=config
  124. */
  125. search_pb = slapi_pblock_new();
  126. slapi_search_internal_set_pb(search_pb, cb->pluginDN, LDAP_SCOPE_ONELEVEL,
  127. CB_CONFIG_INSTANCE_FILTER,NULL,0,NULL,NULL,cb->identity, 0);
  128. slapi_search_internal_pb (search_pb);
  129. slapi_pblock_get(search_pb, SLAPI_PLUGIN_INTOP_RESULT, &res);
  130. if (res != LDAP_SUCCESS) {
  131. slapi_log_error(SLAPI_LOG_PLUGIN, CB_PLUGIN_SUBSYSTEM,
  132. "Error accessing the config DSE (%s)\n",ldap_err2string(res));
  133. slapi_free_search_results_internal(search_pb);
  134. slapi_pblock_destroy(search_pb);
  135. return 1;
  136. }
  137. /* Get the default instance value entry if it exists */
  138. /* else create it */
  139. PR_snprintf(defaultDn,sizeof(defaultDn),"cn=default instance config,%s",cb->pluginDN);
  140. default_pb = slapi_pblock_new();
  141. slapi_search_internal_set_pb(default_pb, defaultDn, LDAP_SCOPE_BASE,
  142. "objectclass=*", NULL, 0, NULL, NULL, cb->identity, 0);
  143. slapi_search_internal_pb (default_pb);
  144. slapi_pblock_get(default_pb, SLAPI_PLUGIN_INTOP_RESULT, &default_res);
  145. if (LDAP_SUCCESS != default_res) {
  146. cb_create_default_backend_instance_config(cb);
  147. }
  148. slapi_free_search_results_internal(default_pb);
  149. slapi_pblock_destroy(default_pb);
  150. slapi_pblock_get(search_pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, &entries);
  151. for (i=0; entries && entries[i]; i++) {
  152. int retcode;
  153. char * aDn=slapi_entry_get_dn(entries[i]);
  154. slapi_dn_normalize(aDn);
  155. cb_instance_add_config_callback(pb,entries[i],NULL,&retcode,NULL,cb);
  156. }
  157. slapi_free_search_results_internal(search_pb);
  158. slapi_pblock_destroy(search_pb);
  159. /* Add callbacks */
  160. slapi_config_register_callback(SLAPI_OPERATION_MODIFY, DSE_FLAG_PREOP, cb->configDN,
  161. LDAP_SCOPE_BASE, "(objectclass=*)",cb_config_modify_check_callback, (void *) cb);
  162. slapi_config_register_callback(SLAPI_OPERATION_MODIFY, DSE_FLAG_POSTOP, cb->configDN,
  163. LDAP_SCOPE_BASE, "(objectclass=*)",cb_config_modify_callback, (void *) cb);
  164. slapi_config_register_callback(SLAPI_OPERATION_ADD, DSE_FLAG_PREOP, cb->configDN,
  165. LDAP_SCOPE_BASE, "(objectclass=*)",cb_config_add_check_callback, (void *) cb);
  166. slapi_config_register_callback(SLAPI_OPERATION_ADD, DSE_FLAG_POSTOP, cb->configDN,
  167. LDAP_SCOPE_BASE, "(objectclass=*)",cb_config_add_callback, (void *) cb);
  168. slapi_config_register_callback(SLAPI_OPERATION_SEARCH, DSE_FLAG_PREOP, cb->configDN,
  169. LDAP_SCOPE_BASE, "(objectclass=*)",cb_config_search_callback, (void *) cb);
  170. /* instance creation */
  171. slapi_config_register_callback(SLAPI_OPERATION_ADD, DSE_FLAG_PREOP, cb->pluginDN,
  172. LDAP_SCOPE_SUBTREE, CB_CONFIG_INSTANCE_FILTER, cb_config_add_instance_check_callback, (void *) cb);
  173. slapi_config_register_callback(SLAPI_OPERATION_ADD, DSE_FLAG_POSTOP, cb->pluginDN,
  174. LDAP_SCOPE_SUBTREE, CB_CONFIG_INSTANCE_FILTER, cb_config_add_instance_callback, (void *) cb);
  175. return 0;
  176. }
  177. /* Check validity of the modification */
  178. int cb_config_add_check_callback(Slapi_PBlock *pb, Slapi_Entry* e, Slapi_Entry* e2, int *returncode,
  179. char *returntext, void *arg)
  180. {
  181. Slapi_Attr *attr = NULL;
  182. Slapi_Value *sval;
  183. struct berval * bval;
  184. int i;
  185. cb_backend *cb = (cb_backend *) arg;
  186. CB_ASSERT (cb!=NULL);
  187. for (slapi_entry_first_attr(e, &attr); attr; slapi_entry_next_attr(e, attr, &attr)) {
  188. char * attr_name=NULL;
  189. slapi_attr_get_type(attr, &attr_name);
  190. if ( !strcasecmp ( attr_name, CB_CONFIG_GLOBAL_FORWARD_CTRLS )) {
  191. /* First, parse the values to make sure they are valid */
  192. i = slapi_attr_first_value(attr, &sval);
  193. while (i != -1 ) {
  194. bval = (struct berval *) slapi_value_get_berval(sval);
  195. if (!cb_is_control_forwardable(cb,bval->bv_val)) {
  196. slapi_log_error(SLAPI_LOG_PLUGIN,CB_PLUGIN_SUBSYSTEM,
  197. "control %s can't be forwarded.\n",bval->bv_val);
  198. *returncode=LDAP_CONSTRAINT_VIOLATION;
  199. return SLAPI_DSE_CALLBACK_ERROR;
  200. }
  201. i = slapi_attr_next_value(attr, i, &sval);
  202. }
  203. }
  204. }
  205. *returncode=LDAP_SUCCESS;
  206. return SLAPI_DSE_CALLBACK_OK;
  207. }
  208. /*
  209. ** Global config is beeing added
  210. ** Take the new values into account
  211. */
  212. int
  213. cb_config_add_callback(Slapi_PBlock *pb, Slapi_Entry* e, Slapi_Entry* e2, int *returncode,
  214. char *returntext, void *arg)
  215. {
  216. Slapi_Attr *attr = NULL;
  217. Slapi_Value *sval;
  218. struct berval * bval;
  219. int i;
  220. cb_backend *cb = (cb_backend *) arg;
  221. CB_ASSERT (cb!=NULL);
  222. for (slapi_entry_first_attr(e, &attr); attr; slapi_entry_next_attr(e, attr, &attr)) {
  223. char * attr_name=NULL;
  224. slapi_attr_get_type(attr, &attr_name);
  225. if ( !strcasecmp ( attr_name, CB_CONFIG_GLOBAL_FORWARD_CTRLS )) {
  226. /* First, parse the values to make sure they are valid */
  227. i = slapi_attr_first_value(attr, &sval);
  228. while (i != -1 ) {
  229. bval = (struct berval *) slapi_value_get_berval(sval);
  230. if (!cb_is_control_forwardable(cb,bval->bv_val)) {
  231. slapi_log_error(SLAPI_LOG_PLUGIN,CB_PLUGIN_SUBSYSTEM,
  232. "control %s can't be forwarded.\n",bval->bv_val);
  233. *returncode=LDAP_CONSTRAINT_VIOLATION;
  234. return SLAPI_DSE_CALLBACK_ERROR;
  235. }
  236. i = slapi_attr_next_value(attr, i, &sval);
  237. }
  238. /* second pass. apply changes */
  239. cb_unregister_all_supported_control(cb);
  240. i = slapi_attr_first_value(attr, &sval);
  241. while (i != -1 ) {
  242. bval = (struct berval *) slapi_value_get_berval(sval);
  243. cb_register_supported_control(cb,bval->bv_val,0);
  244. i = slapi_attr_next_value(attr, i, &sval);
  245. }
  246. }
  247. }
  248. *returncode=LDAP_SUCCESS;
  249. return SLAPI_DSE_CALLBACK_OK;
  250. }
  251. int
  252. cb_config_search_callback(Slapi_PBlock *pb, Slapi_Entry* e, Slapi_Entry* e2, int *returncode,
  253. char *returntext, void *arg) {
  254. cb_backend *cb = (cb_backend *) arg;
  255. struct berval val;
  256. struct berval *vals[2];
  257. int i = 0;
  258. CB_ASSERT (cb!=NULL);
  259. vals[0] = &val;
  260. vals[1] = NULL;
  261. /* naming attribute */
  262. val.bv_val = "config";
  263. val.bv_len = strlen( val.bv_val );
  264. slapi_entry_attr_replace( e, "cn", (struct berval **)vals );
  265. /* objectclass attribute */
  266. val.bv_val = "top";
  267. val.bv_len = strlen( val.bv_val );
  268. slapi_entry_attr_replace( e, "objectclass", (struct berval **)vals );
  269. val.bv_val = CB_CONFIG_EXTENSIBLEOCL;
  270. val.bv_len = strlen( val.bv_val );
  271. slapi_entry_attr_merge( e, "objectclass", (struct berval **)vals );
  272. /* other attributes */
  273. PR_RWLock_Rlock(cb->config.rwl_config_lock);
  274. for (i=0; cb->config.forward_ctrls && cb->config.forward_ctrls[i] ; i++) {
  275. val.bv_val=cb->config.forward_ctrls[i];
  276. val.bv_len = strlen( val.bv_val );
  277. if (i==0)
  278. slapi_entry_attr_replace( e, CB_CONFIG_GLOBAL_FORWARD_CTRLS, (struct berval **)vals );
  279. else
  280. slapi_entry_attr_merge( e, CB_CONFIG_GLOBAL_FORWARD_CTRLS, (struct berval **)vals );
  281. }
  282. for (i=0;cb->config.chaining_components && cb->config.chaining_components[i];i++) {
  283. val.bv_val=cb->config.chaining_components[i];
  284. val.bv_len = strlen( val.bv_val );
  285. if (i==0)
  286. slapi_entry_attr_replace( e, CB_CONFIG_GLOBAL_CHAINING_COMPONENTS,
  287. (struct berval **)vals );
  288. else
  289. slapi_entry_attr_merge( e, CB_CONFIG_GLOBAL_CHAINING_COMPONENTS,
  290. (struct berval **)vals );
  291. }
  292. for (i=0; cb->config.chainable_components && cb->config.chainable_components[i]; i++) {
  293. val.bv_val=cb->config.chainable_components[i];
  294. val.bv_len = strlen( val.bv_val );
  295. if (i==0)
  296. slapi_entry_attr_replace( e, CB_CONFIG_GLOBAL_CHAINABLE_COMPONENTS,
  297. (struct berval **)vals );
  298. else
  299. slapi_entry_attr_merge( e, CB_CONFIG_GLOBAL_CHAINABLE_COMPONENTS,
  300. (struct berval **)vals );
  301. }
  302. PR_RWLock_Unlock(cb->config.rwl_config_lock);
  303. *returncode = LDAP_SUCCESS;
  304. return SLAPI_DSE_CALLBACK_OK;
  305. }
  306. /* Check validity of the modification */
  307. int
  308. cb_config_modify_check_callback(Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entry* e, int *returncode,
  309. char *returntext, void *arg)
  310. {
  311. LDAPMod **mods;
  312. char *attr_name;
  313. int i,j;
  314. cb_backend *cb = (cb_backend *) arg;
  315. CB_ASSERT (cb!=NULL);
  316. slapi_pblock_get( pb, SLAPI_MODIFY_MODS, &mods );
  317. for (i = 0; mods[i] ; i++) {
  318. attr_name = mods[i]->mod_type;
  319. if ( !strcasecmp ( attr_name, CB_CONFIG_GLOBAL_FORWARD_CTRLS )) {
  320. char * config_attr_value;
  321. for (j = 0; mods[i]->mod_bvalues && mods[i]->mod_bvalues[j]; j++) {
  322. config_attr_value = (char *) mods[i]->mod_bvalues[j]->bv_val;
  323. if (!cb_is_control_forwardable(cb,config_attr_value)) {
  324. slapi_log_error(SLAPI_LOG_PLUGIN,CB_PLUGIN_SUBSYSTEM,
  325. "control %s can't be forwarded.\n",config_attr_value);
  326. *returncode=LDAP_CONSTRAINT_VIOLATION;
  327. return SLAPI_DSE_CALLBACK_ERROR;
  328. }
  329. }
  330. }
  331. }
  332. *returncode=LDAP_SUCCESS;
  333. return SLAPI_DSE_CALLBACK_OK;
  334. }
  335. int
  336. cb_config_modify_callback(Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entry* e, int *returncode,
  337. char *returntext, void *arg)
  338. {
  339. LDAPMod **mods;
  340. char *attr_name;
  341. int i,j;
  342. cb_backend *cb = (cb_backend *) arg;
  343. CB_ASSERT (cb!=NULL);
  344. slapi_pblock_get( pb, SLAPI_MODIFY_MODS, &mods );
  345. for (i = 0; mods[i] ; i++) {
  346. attr_name = mods[i]->mod_type;
  347. if ( !strcasecmp ( attr_name, CB_CONFIG_GLOBAL_FORWARD_CTRLS )) {
  348. char * config_attr_value;
  349. int done=0;
  350. for (j = 0; mods[i]->mod_bvalues && mods[i]->mod_bvalues[j]; j++) {
  351. config_attr_value = (char *) mods[i]->mod_bvalues[j]->bv_val;
  352. if (!cb_is_control_forwardable(cb,config_attr_value)) {
  353. slapi_log_error(SLAPI_LOG_PLUGIN,CB_PLUGIN_SUBSYSTEM,
  354. "control %s can't be forwarded.\n",config_attr_value);
  355. *returncode=LDAP_CONSTRAINT_VIOLATION;
  356. return SLAPI_DSE_CALLBACK_ERROR;
  357. }
  358. if ( mods[i]->mod_op & LDAP_MOD_REPLACE) {
  359. if (!done) {
  360. cb_unregister_all_supported_control(cb);
  361. done=1;
  362. }
  363. cb_register_supported_control(cb,config_attr_value,0);
  364. } else
  365. if ( (mods[i]->mod_op & ~LDAP_MOD_BVALUES) == LDAP_MOD_ADD) {
  366. cb_register_supported_control(cb,config_attr_value,0);
  367. } else
  368. if ( (mods[i]->mod_op & ~LDAP_MOD_BVALUES) == LDAP_MOD_DELETE) {
  369. cb_unregister_supported_control(cb,config_attr_value,0);
  370. }
  371. }
  372. if (NULL == mods[i]->mod_bvalues)
  373. cb_unregister_all_supported_control(cb);
  374. } else
  375. if ( !strcasecmp ( attr_name, CB_CONFIG_GLOBAL_DEBUG )) {
  376. /* assume single-valued */
  377. if (mods[i]->mod_op & LDAP_MOD_DELETE)
  378. cb_set_debug(0);
  379. else if ((mods[i]->mod_op & ~LDAP_MOD_BVALUES) == LDAP_MOD_ADD)
  380. cb_set_debug(1);
  381. } else
  382. if ( !strcasecmp ( attr_name, CB_CONFIG_GLOBAL_CHAINING_COMPONENTS )) {
  383. char * config_attr_value;
  384. int done=0;
  385. PR_RWLock_Wlock(cb->config.rwl_config_lock);
  386. for (j = 0; mods[i]->mod_bvalues && mods[i]->mod_bvalues[j]; j++) {
  387. config_attr_value = (char *) mods[i]->mod_bvalues[j]->bv_val;
  388. if ( mods[i]->mod_op & LDAP_MOD_REPLACE) {
  389. if (!done) {
  390. charray_free(cb->config.chaining_components);
  391. cb->config.chaining_components=NULL;
  392. done=1;
  393. }
  394. /* XXXSD assume dn. Normalize it */
  395. charray_add(&cb->config.chaining_components,
  396. slapi_dn_normalize(slapi_ch_strdup(config_attr_value)));
  397. } else
  398. if ( (mods[i]->mod_op & ~LDAP_MOD_BVALUES) == LDAP_MOD_ADD) {
  399. charray_add(&cb->config.chaining_components,
  400. slapi_dn_normalize(slapi_ch_strdup(config_attr_value)));
  401. } else
  402. if ( (mods[i]->mod_op & ~LDAP_MOD_BVALUES) == LDAP_MOD_DELETE) {
  403. charray_remove(cb->config.chaining_components,
  404. slapi_dn_normalize(slapi_ch_strdup(config_attr_value)));
  405. }
  406. }
  407. if (NULL == mods[i]->mod_bvalues) {
  408. charray_free(cb->config.chaining_components);
  409. cb->config.chaining_components=NULL;
  410. }
  411. PR_RWLock_Unlock(cb->config.rwl_config_lock);
  412. } else
  413. if ( !strcasecmp ( attr_name, CB_CONFIG_GLOBAL_CHAINABLE_COMPONENTS )) {
  414. char * config_attr_value;
  415. int done=0;
  416. PR_RWLock_Wlock(cb->config.rwl_config_lock);
  417. for (j = 0; mods[i]->mod_bvalues && mods[i]->mod_bvalues[j]; j++) {
  418. config_attr_value = (char *) mods[i]->mod_bvalues[j]->bv_val;
  419. if ( mods[i]->mod_op & LDAP_MOD_REPLACE) {
  420. if (!done) {
  421. charray_free(cb->config.chainable_components);
  422. cb->config.chainable_components=NULL;
  423. done=1;
  424. }
  425. charray_add(&cb->config.chainable_components,
  426. slapi_dn_normalize(slapi_ch_strdup(config_attr_value)
  427. ));
  428. } else
  429. if ( (mods[i]->mod_op & ~LDAP_MOD_BVALUES) == LDAP_MOD_ADD) {
  430. charray_add(&cb->config.chainable_components,
  431. slapi_dn_normalize(slapi_ch_strdup(config_attr_value)
  432. ));
  433. } else
  434. if ( (mods[i]->mod_op & ~LDAP_MOD_BVALUES) == LDAP_MOD_DELETE) {
  435. charray_remove(cb->config.chainable_components,
  436. slapi_dn_normalize(slapi_ch_strdup(config_attr_value)
  437. ));
  438. }
  439. }
  440. if (NULL == mods[i]->mod_bvalues) {
  441. charray_free(cb->config.chainable_components);
  442. cb->config.chainable_components=NULL;
  443. }
  444. PR_RWLock_Unlock(cb->config.rwl_config_lock);
  445. }
  446. }
  447. *returncode=LDAP_SUCCESS;
  448. return SLAPI_DSE_CALLBACK_OK;
  449. }
  450. /*
  451. ** Creation of a new backend instance
  452. */
  453. int
  454. cb_config_add_instance_callback(Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entry* e, int *returncode,
  455. char *returntext, void *arg)
  456. {
  457. cb_backend *cb=(cb_backend *)arg;
  458. CB_ASSERT(cb!=NULL);
  459. cb_instance_add_config_callback(pb,entryBefore,NULL,returncode,returntext,cb);
  460. return SLAPI_DSE_CALLBACK_OK;
  461. }
  462. int
  463. cb_config_add_instance_check_callback(Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entry* e, int *returncode,
  464. char *returntext, void *arg)
  465. {
  466. cb_backend *cb=(cb_backend *)arg;
  467. CB_ASSERT(cb!=NULL);
  468. return cb_instance_add_config_check_callback(pb,entryBefore,NULL,returncode,returntext,cb);
  469. }
  470. /*
  471. ** Parse the global chaining backend configuration
  472. */
  473. static int cb_parse_config_entry(cb_backend * cb, Slapi_Entry *e)
  474. {
  475. Slapi_Attr *attr = NULL;
  476. Slapi_Value *sval;
  477. struct berval *bval;
  478. int i;
  479. if (e == NULL)
  480. return LDAP_SUCCESS;
  481. cb_set_debug(0);
  482. for (slapi_entry_first_attr(e, &attr); attr; slapi_entry_next_attr(e, attr, &attr)) {
  483. char * attr_name=NULL;
  484. slapi_attr_get_type(attr, &attr_name);
  485. if ( !strcasecmp ( attr_name, CB_CONFIG_GLOBAL_FORWARD_CTRLS )) {
  486. i = slapi_attr_first_value(attr, &sval);
  487. PR_RWLock_Wlock(cb->config.rwl_config_lock);
  488. if (cb->config.forward_ctrls) {
  489. charray_free(cb->config.forward_ctrls);
  490. cb->config.forward_ctrls=NULL;
  491. }
  492. PR_RWLock_Unlock(cb->config.rwl_config_lock);
  493. while (i != -1 ) {
  494. bval = (struct berval *) slapi_value_get_berval(sval);
  495. /* For now, don't support operation type */
  496. cb_register_supported_control(cb,bval->bv_val,
  497. SLAPI_OPERATION_SEARCH | SLAPI_OPERATION_COMPARE |
  498. SLAPI_OPERATION_ADD | SLAPI_OPERATION_DELETE |
  499. SLAPI_OPERATION_MODIFY | SLAPI_OPERATION_MODDN);
  500. i = slapi_attr_next_value(attr, i, &sval);
  501. }
  502. } else
  503. if ( !strcasecmp ( attr_name, CB_CONFIG_GLOBAL_CHAINING_COMPONENTS )) {
  504. i = slapi_attr_first_value(attr, &sval);
  505. PR_RWLock_Wlock(cb->config.rwl_config_lock);
  506. if (cb->config.chaining_components) {
  507. charray_free(cb->config.chaining_components);
  508. cb->config.chaining_components=NULL;
  509. }
  510. while (i != -1 ) {
  511. bval = (struct berval *) slapi_value_get_berval(sval);
  512. /* XXXSD assume dn. Normalize it */
  513. charray_add( &cb->config.chaining_components,
  514. slapi_dn_normalize(slapi_ch_strdup(bval->bv_val)));
  515. i = slapi_attr_next_value(attr, i, &sval);
  516. }
  517. PR_RWLock_Unlock(cb->config.rwl_config_lock);
  518. } else
  519. if ( !strcasecmp ( attr_name, CB_CONFIG_GLOBAL_CHAINABLE_COMPONENTS )) {
  520. i = slapi_attr_first_value(attr, &sval);
  521. PR_RWLock_Wlock(cb->config.rwl_config_lock);
  522. if (cb->config.chainable_components) {
  523. charray_free(cb->config.chainable_components);
  524. cb->config.chainable_components=NULL;
  525. }
  526. while (i != -1 ) {
  527. bval = (struct berval *) slapi_value_get_berval(sval);
  528. charray_add( &cb->config.chainable_components,
  529. slapi_dn_normalize(slapi_ch_strdup(bval->bv_val)));
  530. i = slapi_attr_next_value(attr, i, &sval);
  531. }
  532. PR_RWLock_Unlock(cb->config.rwl_config_lock);
  533. } else
  534. if ( !strcasecmp ( attr_name, CB_CONFIG_GLOBAL_DEBUG )) {
  535. i = slapi_attr_first_value(attr, &sval);
  536. if (i != -1 ) {
  537. bval = (struct berval *) slapi_value_get_berval(sval);
  538. /* any value */
  539. cb_set_debug(1);
  540. }
  541. }
  542. }
  543. return LDAP_SUCCESS;
  544. }