backend.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559
  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. /* backend.c - Slapi_Backend methods */
  42. #include "slap.h"
  43. void
  44. be_init( Slapi_Backend *be, const char *type, const char *name, int isprivate, int logchanges, int sizelimit, int timelimit )
  45. {
  46. char text[128];
  47. slapdFrontendConfig_t *fecfg;
  48. be->be_suffix = NULL;
  49. be->be_suffixlock= PR_NewLock();
  50. be->be_suffixcount= 0;
  51. /* e.g. dn: cn=config,cn=NetscapeRoot,cn=ldbm database,cn=plugins,cn=config */
  52. PR_snprintf(text, sizeof(text),"cn=%s,cn=%s,cn=plugins,cn=config", name, type);
  53. be->be_basedn= slapi_ch_strdup(slapi_dn_normalize(text));
  54. PR_snprintf(text, sizeof(text), "cn=config,cn=%s,cn=%s,cn=plugins,cn=config", name, type);
  55. be->be_configdn= slapi_ch_strdup(slapi_dn_normalize(text));
  56. PR_snprintf(text, sizeof(text), "cn=monitor,cn=%s,cn=%s,cn=plugins,cn=config", name, type);
  57. be->be_monitordn= slapi_ch_strdup(slapi_dn_normalize(text));
  58. be->be_sizelimit = sizelimit;
  59. be->be_timelimit = timelimit;
  60. /* maximum group nesting level before giving up */
  61. be->be_maxnestlevel = SLAPD_DEFAULT_GROUPNESTLEVEL;
  62. be->be_noacl= 0;
  63. be->be_flags=0;
  64. if (( fecfg = getFrontendConfig()) != NULL )
  65. {
  66. if ( fecfg->backendconfig != NULL && fecfg->backendconfig[ 0 ] != NULL )
  67. {
  68. be->be_backendconfig = slapi_ch_strdup( fecfg->backendconfig[0] );
  69. }
  70. else
  71. {
  72. be->be_backendconfig= NULL;
  73. }
  74. be->be_readonly = fecfg->readonly;
  75. }
  76. else
  77. {
  78. be->be_readonly= 0;
  79. be->be_backendconfig= NULL;
  80. }
  81. be->be_lastmod = LDAP_UNDEFINED;
  82. be->be_type = slapi_ch_strdup(type);
  83. be->be_include = NULL;
  84. be->be_private = isprivate;
  85. be->be_logchanges = logchanges;
  86. be->be_database = NULL;
  87. be->be_writeconfig = NULL;
  88. be->be_delete_on_exit = 0;
  89. be->be_state = BE_STATE_STOPPED;
  90. be->be_state_lock = PR_NewLock();
  91. be->be_name = slapi_ch_strdup(name);
  92. be->be_mapped = 0;
  93. }
  94. void
  95. be_done(Slapi_Backend *be)
  96. {
  97. int i;
  98. for(i=0;i<be->be_suffixcount;i++)
  99. {
  100. slapi_sdn_free(&be->be_suffix[i]);
  101. }
  102. slapi_ch_free((void**)&be->be_suffix);
  103. PR_DestroyLock(be->be_suffixlock);
  104. slapi_ch_free((void **)&be->be_basedn);
  105. slapi_ch_free((void **)&be->be_configdn);
  106. slapi_ch_free((void **)&be->be_monitordn);
  107. slapi_ch_free((void **)&be->be_type);
  108. slapi_ch_free((void **)&be->be_backendconfig);
  109. /* JCM char **be_include; ??? */
  110. slapi_ch_free((void **)&be->be_name);
  111. PR_DestroyLock(be->be_state_lock);
  112. if (be->be_lock != NULL)
  113. {
  114. PR_DestroyRWLock(be->be_lock);
  115. be->be_lock = NULL;
  116. }
  117. }
  118. void
  119. slapi_be_delete_onexit (Slapi_Backend *be)
  120. {
  121. be->be_delete_on_exit = 1;
  122. }
  123. void
  124. slapi_be_set_readonly(Slapi_Backend *be, int readonly)
  125. {
  126. be->be_readonly = readonly;
  127. }
  128. int
  129. slapi_be_get_readonly(Slapi_Backend *be)
  130. {
  131. return be->be_readonly;
  132. }
  133. /*
  134. * Check if suffix, exactly matches a registered
  135. * suffix of this backend.
  136. */
  137. int
  138. slapi_be_issuffix( const Slapi_Backend *be, const Slapi_DN *suffix )
  139. {
  140. int r= 0;
  141. /* this backend is no longer valid */
  142. if (be->be_state != BE_STATE_DELETED)
  143. {
  144. int i;
  145. PR_Lock(be->be_suffixlock);
  146. for ( i = 0; be->be_suffix != NULL && i<be->be_suffixcount; i++ )
  147. {
  148. if ( slapi_sdn_compare( be->be_suffix[i], suffix ) == 0)
  149. {
  150. r= 1;
  151. break;
  152. }
  153. }
  154. PR_Unlock(be->be_suffixlock);
  155. }
  156. return r;
  157. }
  158. int
  159. be_isdeleted( const Slapi_Backend *be )
  160. {
  161. return ((be == NULL) || (BE_STATE_DELETED == be->be_state));
  162. }
  163. void
  164. be_addsuffix(Slapi_Backend *be,const Slapi_DN *suffix)
  165. {
  166. if (be->be_state != BE_STATE_DELETED)
  167. {
  168. PR_Lock(be->be_suffixlock);
  169. if(be->be_suffix==NULL)
  170. {
  171. be->be_suffix= (Slapi_DN **)slapi_ch_malloc(sizeof(Slapi_DN *));
  172. }
  173. else
  174. {
  175. be->be_suffix= (Slapi_DN **)slapi_ch_realloc((char*)be->be_suffix,(be->be_suffixcount+1)*sizeof(Slapi_DN *));
  176. }
  177. be->be_suffix[be->be_suffixcount]= slapi_sdn_dup(suffix);
  178. be->be_suffixcount++;
  179. PR_Unlock(be->be_suffixlock);
  180. }
  181. }
  182. void slapi_be_addsuffix(Slapi_Backend *be,const Slapi_DN *suffix)
  183. {
  184. be_addsuffix(be,suffix);
  185. }
  186. /*
  187. * The caller may use the returned pointer without holding the
  188. * be_suffixlock since we never remove suffixes from the array.
  189. * The Slapi_DN pointer will always be valid even though the array
  190. * itself may be changing due to the addition of a suffix.
  191. */
  192. const Slapi_DN *
  193. slapi_be_getsuffix(Slapi_Backend *be,int n)
  194. {
  195. Slapi_DN *sdn = NULL;
  196. if(NULL == be)
  197. return NULL;
  198. if(be->be_state != BE_STATE_DELETED) {
  199. PR_Lock(be->be_suffixlock);
  200. if (be->be_suffix !=NULL && n<be->be_suffixcount) {
  201. sdn = be->be_suffix[n];
  202. }
  203. PR_Unlock(be->be_suffixlock);
  204. }
  205. return sdn;
  206. }
  207. const char *
  208. slapi_be_gettype(Slapi_Backend *be)
  209. {
  210. const char *r= NULL;
  211. if (be->be_state != BE_STATE_DELETED)
  212. {
  213. r= be->be_type;
  214. }
  215. return r;
  216. }
  217. Slapi_DN *
  218. be_getconfigdn(Slapi_Backend *be, Slapi_DN *dn)
  219. {
  220. if (be->be_state == BE_STATE_DELETED)
  221. {
  222. slapi_sdn_set_ndn_byref(dn,NULL);
  223. }
  224. else
  225. {
  226. slapi_sdn_set_ndn_byref(dn,be->be_configdn);
  227. }
  228. return dn;
  229. }
  230. Slapi_DN *
  231. be_getmonitordn(Slapi_Backend *be, Slapi_DN *dn)
  232. {
  233. if (be->be_state == BE_STATE_DELETED)
  234. {
  235. slapi_sdn_set_ndn_byref(dn,NULL);
  236. }
  237. else
  238. {
  239. slapi_sdn_set_ndn_byref(dn,be->be_monitordn);
  240. }
  241. return dn;
  242. }
  243. int
  244. be_writeconfig ( Slapi_Backend *be )
  245. {
  246. Slapi_PBlock *newpb;
  247. if (be->be_state == BE_STATE_DELETED || be->be_private ||
  248. (be->be_writeconfig == NULL) ) {
  249. return -1;
  250. }
  251. else {
  252. newpb = slapi_pblock_new();
  253. slapi_pblock_set ( newpb, SLAPI_PLUGIN, (void *) be->be_database );
  254. slapi_pblock_set ( newpb, SLAPI_BACKEND, (void *) be );
  255. (be->be_writeconfig)(newpb);
  256. slapi_pblock_destroy ( newpb );
  257. return 1;
  258. }
  259. }
  260. /*
  261. * Find out if changes made to entries in this backend
  262. * should be recorded in the changelog.
  263. */
  264. int
  265. slapi_be_logchanges(Slapi_Backend *be)
  266. {
  267. if (be->be_state == BE_STATE_DELETED)
  268. return 0;
  269. return be->be_logchanges;
  270. }
  271. int
  272. slapi_be_private ( Slapi_Backend *be )
  273. {
  274. if ( be!=NULL )
  275. {
  276. return (be->be_private);
  277. }
  278. return 0;
  279. }
  280. void *
  281. slapi_be_get_instance_info(Slapi_Backend * be)
  282. {
  283. PR_ASSERT(NULL != be);
  284. return be->be_instance_info;
  285. }
  286. void
  287. slapi_be_set_instance_info(Slapi_Backend * be, void * data)
  288. {
  289. PR_ASSERT(NULL != be);
  290. be->be_instance_info=data;
  291. }
  292. int
  293. slapi_be_getentrypoint(Slapi_Backend *be, int entrypoint, void **ret_fnptr, Slapi_PBlock *pb)
  294. {
  295. PR_ASSERT(NULL != be);
  296. /* this is something needed for most of the entry points */
  297. if (pb)
  298. {
  299. slapi_pblock_set( pb, SLAPI_PLUGIN, be->be_database );
  300. slapi_pblock_set( pb, SLAPI_BACKEND, be );
  301. }
  302. switch (entrypoint) {
  303. case SLAPI_PLUGIN_DB_BIND_FN:
  304. *ret_fnptr = (void*)be->be_bind;
  305. break;
  306. case SLAPI_PLUGIN_DB_UNBIND_FN:
  307. *ret_fnptr = (void*)be->be_unbind;
  308. break;
  309. case SLAPI_PLUGIN_DB_SEARCH_FN:
  310. *ret_fnptr = (void*)be->be_search;
  311. break;
  312. case SLAPI_PLUGIN_DB_COMPARE_FN:
  313. *ret_fnptr = (void*)be->be_compare;
  314. break;
  315. case SLAPI_PLUGIN_DB_MODIFY_FN:
  316. *ret_fnptr = (void*)be->be_modify;
  317. break;
  318. case SLAPI_PLUGIN_DB_MODRDN_FN:
  319. *ret_fnptr = (void*)be->be_modrdn;
  320. break;
  321. case SLAPI_PLUGIN_DB_ADD_FN:
  322. *ret_fnptr = (void*)be->be_add;
  323. break;
  324. case SLAPI_PLUGIN_DB_DELETE_FN:
  325. *ret_fnptr = (void*)be->be_delete;
  326. break;
  327. case SLAPI_PLUGIN_DB_ABANDON_FN:
  328. *ret_fnptr = (void*)be->be_abandon;
  329. break;
  330. case SLAPI_PLUGIN_DB_CONFIG_FN:
  331. *ret_fnptr = (void*)be->be_config;
  332. break;
  333. case SLAPI_PLUGIN_CLOSE_FN:
  334. *ret_fnptr = (void*)be->be_close;
  335. break;
  336. case SLAPI_PLUGIN_DB_FLUSH_FN:
  337. *ret_fnptr = (void*)be->be_flush;
  338. break;
  339. case SLAPI_PLUGIN_START_FN:
  340. *ret_fnptr = (void*)be->be_start;
  341. break;
  342. case SLAPI_PLUGIN_DB_RESULT_FN:
  343. *ret_fnptr = (void*)be->be_result;
  344. break;
  345. case SLAPI_PLUGIN_DB_LDIF2DB_FN:
  346. *ret_fnptr = (void*)be->be_ldif2db;
  347. break;
  348. case SLAPI_PLUGIN_DB_DB2LDIF_FN:
  349. *ret_fnptr = (void*)be->be_db2ldif;
  350. break;
  351. case SLAPI_PLUGIN_DB_ARCHIVE2DB_FN:
  352. *ret_fnptr = (void*)be->be_archive2db;
  353. break;
  354. case SLAPI_PLUGIN_DB_DB2ARCHIVE_FN:
  355. *ret_fnptr = (void*)be->be_db2archive;
  356. break;
  357. case SLAPI_PLUGIN_DB_NEXT_SEARCH_ENTRY_FN:
  358. *ret_fnptr = (void*)be->be_next_search_entry;
  359. break;
  360. case SLAPI_PLUGIN_DB_NEXT_SEARCH_ENTRY_EXT_FN:
  361. *ret_fnptr = (void*)be->be_next_search_entry_ext;
  362. break;
  363. case SLAPI_PLUGIN_DB_ENTRY_RELEASE_FN:
  364. *ret_fnptr = (void*)be->be_entry_release;
  365. break;
  366. case SLAPI_PLUGIN_DB_SEARCH_RESULTS_RELEASE_FN:
  367. *ret_fnptr = (void*)be->be_search_results_release;
  368. break;
  369. case SLAPI_PLUGIN_DB_SIZE_FN:
  370. *ret_fnptr = (void*)be->be_dbsize;
  371. break;
  372. case SLAPI_PLUGIN_DB_TEST_FN:
  373. *ret_fnptr = (void*)be->be_dbtest;
  374. break;
  375. case SLAPI_PLUGIN_DB_RMDB_FN:
  376. *ret_fnptr = (void*)be->be_rmdb;
  377. break;
  378. case SLAPI_PLUGIN_DB_INIT_INSTANCE_FN:
  379. *ret_fnptr = (void*)be->be_init_instance;
  380. break;
  381. case SLAPI_PLUGIN_DB_SEQ_FN:
  382. *ret_fnptr = (void*)be->be_seq;
  383. break;
  384. case SLAPI_PLUGIN_DB_DB2INDEX_FN:
  385. *ret_fnptr = (void*)be->be_db2index;
  386. break;
  387. case SLAPI_PLUGIN_CLEANUP_FN:
  388. *ret_fnptr = (void*)be->be_cleanup;
  389. break;
  390. default:
  391. slapi_log_error(SLAPI_LOG_FATAL, NULL,
  392. "slapi_be_getentrypoint: unknown entry point %d\n", entrypoint);
  393. return -1;
  394. }
  395. return 0;
  396. }
  397. int
  398. slapi_be_setentrypoint(Slapi_Backend *be, int entrypoint, void *ret_fnptr, Slapi_PBlock *pb)
  399. {
  400. PR_ASSERT(NULL != be);
  401. /* this is something needed for most of the entry points */
  402. if (pb)
  403. {
  404. be->be_database=pb->pb_plugin;
  405. return 0;
  406. }
  407. switch (entrypoint) {
  408. case SLAPI_PLUGIN_DB_BIND_FN:
  409. be->be_bind=(IFP)ret_fnptr;
  410. break;
  411. case SLAPI_PLUGIN_DB_UNBIND_FN:
  412. be->be_unbind=(IFP)ret_fnptr;
  413. break;
  414. case SLAPI_PLUGIN_DB_SEARCH_FN:
  415. be->be_search=(IFP)ret_fnptr;
  416. break;
  417. case SLAPI_PLUGIN_DB_COMPARE_FN:
  418. be->be_compare=(IFP)ret_fnptr;
  419. break;
  420. case SLAPI_PLUGIN_DB_MODIFY_FN:
  421. be->be_modify=(IFP)ret_fnptr;
  422. break;
  423. case SLAPI_PLUGIN_DB_MODRDN_FN:
  424. be->be_modrdn=(IFP)ret_fnptr;
  425. break;
  426. case SLAPI_PLUGIN_DB_ADD_FN:
  427. be->be_add=(IFP)ret_fnptr;
  428. break;
  429. case SLAPI_PLUGIN_DB_DELETE_FN:
  430. be->be_delete=(IFP)ret_fnptr;
  431. break;
  432. case SLAPI_PLUGIN_DB_ABANDON_FN:
  433. be->be_abandon=(IFP)ret_fnptr;
  434. break;
  435. case SLAPI_PLUGIN_DB_CONFIG_FN:
  436. be->be_config=(IFP)ret_fnptr;
  437. break;
  438. case SLAPI_PLUGIN_CLOSE_FN:
  439. be->be_close=(IFP)ret_fnptr;
  440. break;
  441. case SLAPI_PLUGIN_DB_FLUSH_FN:
  442. be->be_flush=(IFP)ret_fnptr;
  443. break;
  444. case SLAPI_PLUGIN_START_FN:
  445. be->be_start=(IFP)ret_fnptr;
  446. break;
  447. case SLAPI_PLUGIN_DB_RESULT_FN:
  448. be->be_result=(IFP)ret_fnptr;
  449. break;
  450. case SLAPI_PLUGIN_DB_LDIF2DB_FN:
  451. be->be_ldif2db=(IFP)ret_fnptr;
  452. break;
  453. case SLAPI_PLUGIN_DB_DB2LDIF_FN:
  454. be->be_db2ldif=(IFP) ret_fnptr;
  455. break;
  456. case SLAPI_PLUGIN_DB_ARCHIVE2DB_FN:
  457. be->be_archive2db=(IFP) ret_fnptr;
  458. break;
  459. case SLAPI_PLUGIN_DB_DB2ARCHIVE_FN:
  460. be->be_db2archive=(IFP) ret_fnptr;
  461. break;
  462. case SLAPI_PLUGIN_DB_NEXT_SEARCH_ENTRY_FN:
  463. be->be_next_search_entry=(IFP) ret_fnptr;
  464. break;
  465. case SLAPI_PLUGIN_DB_NEXT_SEARCH_ENTRY_EXT_FN:
  466. be->be_next_search_entry_ext=(IFP) ret_fnptr;
  467. break;
  468. case SLAPI_PLUGIN_DB_ENTRY_RELEASE_FN:
  469. be->be_entry_release=(IFP) ret_fnptr;
  470. break;
  471. case SLAPI_PLUGIN_DB_SEARCH_RESULTS_RELEASE_FN:
  472. be->be_search_results_release=(IFP) ret_fnptr;
  473. break;
  474. case SLAPI_PLUGIN_DB_SIZE_FN:
  475. be->be_dbsize=(IFP) ret_fnptr;
  476. break;
  477. case SLAPI_PLUGIN_DB_TEST_FN:
  478. be->be_dbtest=(IFP)ret_fnptr;
  479. break;
  480. case SLAPI_PLUGIN_DB_RMDB_FN:
  481. be->be_rmdb=(IFP)ret_fnptr;
  482. break;
  483. case SLAPI_PLUGIN_DB_INIT_INSTANCE_FN:
  484. be->be_init_instance=(IFP)ret_fnptr;
  485. break;
  486. case SLAPI_PLUGIN_DB_SEQ_FN:
  487. be->be_seq=(IFP)ret_fnptr;
  488. break;
  489. case SLAPI_PLUGIN_DB_DB2INDEX_FN:
  490. be->be_db2index=(IFP)ret_fnptr;
  491. break;
  492. case SLAPI_PLUGIN_CLEANUP_FN:
  493. be->be_cleanup=(IFP)ret_fnptr;
  494. break;
  495. default:
  496. slapi_log_error(SLAPI_LOG_FATAL, NULL,
  497. "slapi_be_setentrypoint: unknown entry point %d\n", entrypoint);
  498. return -1;
  499. }
  500. return 0;
  501. }
  502. int slapi_be_is_flag_set(Slapi_Backend * be, int flag)
  503. {
  504. return be->be_flags & flag;
  505. }
  506. void slapi_be_set_flag(Slapi_Backend * be, int flag)
  507. {
  508. be->be_flags|= flag;
  509. }
  510. char * slapi_be_get_name(Slapi_Backend * be)
  511. {
  512. return be->be_name;
  513. }
  514. void be_set_sizelimit(Slapi_Backend * be, int sizelimit)
  515. {
  516. be->be_sizelimit = sizelimit;
  517. }
  518. void be_set_timelimit(Slapi_Backend * be, int timelimit)
  519. {
  520. be->be_timelimit = timelimit;
  521. }