1
0

cb_config.c 24 KB

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