backend_manager.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524
  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. /* backend_manager.c - routines for dealing with back-end databases */
  13. #include "slap.h"
  14. #define BACKEND_GRAB_SIZE 10
  15. /* JCM - searching the backend array is linear... */
  16. static int defsize = SLAPD_DEFAULT_SIZELIMIT;
  17. static int deftime = SLAPD_DEFAULT_TIMELIMIT;
  18. static int nbackends= 0;
  19. static Slapi_Backend **backends= NULL;
  20. static int maxbackends= 0;
  21. Slapi_Backend *
  22. slapi_be_new( const char *type, const char *name, int isprivate, int logchanges )
  23. {
  24. Slapi_Backend *be;
  25. int i;
  26. /* should add some locking here to prevent concurrent access */
  27. if ( nbackends == maxbackends )
  28. {
  29. int oldsize = maxbackends;
  30. maxbackends += BACKEND_GRAB_SIZE;
  31. backends = (Slapi_Backend **) slapi_ch_realloc( (char *) backends, maxbackends * sizeof(Slapi_Backend *) );
  32. memset( &backends[oldsize], '\0', BACKEND_GRAB_SIZE * sizeof(Slapi_Backend *) );
  33. }
  34. for (i=0; ((i<maxbackends) && (backends[i])); i++)
  35. ;
  36. PR_ASSERT(i<maxbackends);
  37. be = (Slapi_Backend *) slapi_ch_calloc(1, sizeof(Slapi_Backend));
  38. be->be_lock = slapi_new_rwlock();
  39. be_init( be, type, name, isprivate, logchanges, defsize, deftime );
  40. backends[i] = be;
  41. nbackends++;
  42. slapi_log_error(SLAPI_LOG_TRACE, "slapi_be_new",
  43. "Added new backend name [%s] type [%s] nbackends [%d]\n",
  44. name, type, nbackends);
  45. return( be );
  46. }
  47. void
  48. slapi_be_stopping (Slapi_Backend *be)
  49. {
  50. int i;
  51. PR_Lock (be->be_state_lock);
  52. for (i=0; ((i<maxbackends) && backends[i] != be); i++)
  53. ;
  54. PR_ASSERT(i<maxbackends);
  55. backends[i] = NULL;
  56. be->be_state = BE_STATE_DELETED;
  57. if (be->be_lock != NULL)
  58. {
  59. slapi_destroy_rwlock(be->be_lock);
  60. be->be_lock = NULL;
  61. }
  62. nbackends--;
  63. PR_Unlock (be->be_state_lock);
  64. }
  65. void
  66. slapi_be_free(Slapi_Backend **be)
  67. {
  68. be_done(*be);
  69. slapi_ch_free((void**)be);
  70. *be = NULL;
  71. }
  72. static int
  73. be_plgfn_unwillingtoperform(Slapi_PBlock *pb)
  74. {
  75. send_ldap_result( pb, LDAP_UNWILLING_TO_PERFORM, NULL, "Operation on Directory Specific Entry not allowed", 0, NULL );
  76. return -1;
  77. }
  78. /* JCM - Seems rather DSE specific... why's it here?... Should be in fedse.c... */
  79. Slapi_Backend *
  80. be_new_internal(struct dse *pdse, const char *type, const char *name)
  81. {
  82. Slapi_Backend *be= slapi_be_new(type, name, 1 /* Private */, 0 /* Do Not Log Changes */);
  83. be->be_database = (struct slapdplugin *) slapi_ch_calloc( 1, sizeof(struct slapdplugin) );
  84. be->be_database->plg_private= (void*)pdse;
  85. be->be_database->plg_bind= &dse_bind;
  86. be->be_database->plg_unbind= &dse_unbind;
  87. be->be_database->plg_search= &dse_search;
  88. be->be_database->plg_next_search_entry= &dse_next_search_entry;
  89. be->be_database->plg_search_results_release= &dse_search_set_release;
  90. be->be_database->plg_prev_search_results= &dse_prev_search_results;
  91. be->be_database->plg_compare= &be_plgfn_unwillingtoperform;
  92. be->be_database->plg_modify= &dse_modify;
  93. be->be_database->plg_modrdn= &be_plgfn_unwillingtoperform;
  94. be->be_database->plg_add= &dse_add;
  95. be->be_database->plg_delete= &dse_delete;
  96. be->be_database->plg_abandon= &be_plgfn_unwillingtoperform;
  97. be->be_database->plg_cleanup = dse_deletedse;
  98. /* All the other function pointers default to NULL */
  99. return be;
  100. }
  101. /*
  102. * Rule: before coming to this point, slapi_be_Wlock(be) must be acquired.
  103. */
  104. void
  105. be_replace_dse_internal(Slapi_Backend *be, struct dse *pdse)
  106. {
  107. be->be_database->plg_private= (void*)pdse;
  108. }
  109. Slapi_Backend*
  110. slapi_get_first_backend (char **cookie)
  111. {
  112. int i;
  113. for (i = 0; i < maxbackends; i++)
  114. {
  115. if ( backends[i] && (backends[i]->be_state != BE_STATE_DELETED))
  116. {
  117. *cookie = (char*)slapi_ch_malloc (sizeof (int));
  118. memcpy (*cookie, &i, sizeof (int));
  119. return backends[i];
  120. }
  121. }
  122. return NULL;
  123. }
  124. Slapi_Backend*
  125. slapi_get_next_backend (char *cookie)
  126. {
  127. int i, last_be;
  128. if (cookie == NULL)
  129. {
  130. LDAPDebug( LDAP_DEBUG_ARGS, "slapi_get_next_backend: NULL argument\n",
  131. 0, 0, 0 );
  132. return NULL;
  133. }
  134. last_be = *(int *)cookie;
  135. if ( last_be < 0 || last_be >= maxbackends)
  136. {
  137. LDAPDebug( LDAP_DEBUG_ARGS, "slapi_get_next_backend: argument out of range\n",
  138. 0, 0, 0 );
  139. return NULL;
  140. }
  141. if (last_be == maxbackends - 1)
  142. return NULL; /* done */
  143. for (i = last_be + 1; i < maxbackends; i++)
  144. {
  145. if (backends[i] && (backends[i]->be_state != BE_STATE_DELETED))
  146. {
  147. memcpy (cookie, &i, sizeof (int));
  148. return backends [i];
  149. }
  150. }
  151. return NULL;
  152. }
  153. Slapi_Backend *
  154. g_get_user_backend( int n )
  155. {
  156. int i, useri;
  157. useri = 0;
  158. for ( i = 0; i < maxbackends; i++ ) {
  159. if ( (backends[i] == NULL) || (backends[i]->be_private == 1) ) {
  160. continue;
  161. }
  162. if ( useri == n ) {
  163. if (backends[i]->be_state != BE_STATE_DELETED)
  164. return backends[i];
  165. else
  166. return NULL;
  167. }
  168. useri++;
  169. }
  170. return NULL;
  171. }
  172. void
  173. g_set_deftime(int val)
  174. {
  175. deftime = val;
  176. }
  177. void
  178. g_set_defsize(int val)
  179. {
  180. defsize = val;
  181. }
  182. int
  183. g_get_deftime()
  184. {
  185. return deftime;
  186. }
  187. int
  188. g_get_defsize()
  189. {
  190. return defsize;
  191. }
  192. int strtrimcasecmp(const char *s1, const char *s2)
  193. {
  194. char * s1bis, *s2bis;
  195. int len_s1 = 0, len_s2 = 0;
  196. if ( ((s1 == NULL) && (s2 != NULL))
  197. || ((s2 == NULL) && (s1 != NULL)) )
  198. return 1;
  199. if ((s1 == NULL) && (s2 == NULL))
  200. return 0;
  201. while (*s1 == ' ')
  202. s1++;
  203. while (*s2 == ' ')
  204. s2++;
  205. s1bis = (char *) s1;
  206. while ((*s1bis != ' ') && (*s1bis != 0))
  207. {
  208. len_s1 ++;
  209. s1bis ++;
  210. }
  211. s2bis = (char *) s2;
  212. while ((*s2bis != ' ') && (*s2bis != 0))
  213. {
  214. len_s2 ++;
  215. s2bis ++;
  216. }
  217. if (len_s2 != len_s1)
  218. return 1;
  219. return strncasecmp(s1, s2, len_s1);
  220. }
  221. /*
  222. * Find the backend of the given type.
  223. */
  224. Slapi_Backend *
  225. slapi_be_select_by_instance_name( const char *name )
  226. {
  227. int i;
  228. for ( i = 0; i < maxbackends; i++ )
  229. {
  230. if ( backends[i] && (backends[i]->be_state != BE_STATE_DELETED) &&
  231. strtrimcasecmp( backends[i]->be_name, name ) == 0)
  232. {
  233. return backends[i];
  234. }
  235. }
  236. return NULL;
  237. }
  238. /* void
  239. be_cleanupall()
  240. {
  241. int i;
  242. Slapi_PBlock pb;
  243. for ( i = 0; i < maxbackends; i++ )
  244. {
  245. if ( backends[i] &&
  246. backends[i]->be_cleanup != NULL &&
  247. (backends[i]->be_state == BE_STATE_STOPPED ||
  248. backends[i]->be_state == BE_STATE_DELETED))
  249. {
  250. slapi_pblock_set( &pb, SLAPI_PLUGIN, backends[i]->be_database );
  251. slapi_pblock_set( &pb, SLAPI_BACKEND, backends[i] );
  252. (*backends[i]->be_cleanup)( &pb );
  253. }
  254. }
  255. }*/
  256. void
  257. be_cleanupall()
  258. {
  259. int i;
  260. Slapi_PBlock pb;
  261. for ( i = 0; i < maxbackends; i++ )
  262. {
  263. if (backends[i] &&
  264. backends[i]->be_cleanup != NULL &&
  265. (backends[i]->be_state == BE_STATE_STOPPED ||
  266. backends[i]->be_state == BE_STATE_DELETED))
  267. {
  268. slapi_pblock_set( &pb, SLAPI_PLUGIN, backends[i]->be_database );
  269. slapi_pblock_set( &pb, SLAPI_BACKEND, backends[i] );
  270. (*backends[i]->be_cleanup)( &pb );
  271. slapi_be_free(&backends[i]);
  272. }
  273. }
  274. slapi_ch_free((void**)&backends);
  275. }
  276. void
  277. be_flushall()
  278. {
  279. int i;
  280. Slapi_PBlock pb;
  281. for ( i = 0; i < maxbackends; i++ )
  282. {
  283. if ( backends[i] &&
  284. backends[i]->be_state == BE_STATE_STARTED &&
  285. backends[i]->be_flush != NULL )
  286. {
  287. slapi_pblock_set( &pb, SLAPI_PLUGIN, backends[i]->be_database );
  288. slapi_pblock_set( &pb, SLAPI_BACKEND, backends[i] );
  289. (*backends[i]->be_flush)( &pb );
  290. }
  291. }
  292. }
  293. void
  294. be_unbindall(Connection *conn, Operation *op)
  295. {
  296. int i;
  297. Slapi_PBlock pb;
  298. for ( i = 0; i < maxbackends; i++ )
  299. {
  300. if ( backends[i] && (backends[i]->be_unbind != NULL) )
  301. {
  302. pblock_init_common( &pb, backends[i], conn, op );
  303. if ( plugin_call_plugins( &pb, SLAPI_PLUGIN_PRE_UNBIND_FN ) == 0 )
  304. {
  305. int rc = 0;
  306. slapi_pblock_set( &pb, SLAPI_PLUGIN, backends[i]->be_database );
  307. if(backends[i]->be_state != BE_STATE_DELETED &&
  308. backends[i]->be_unbind!=NULL)
  309. {
  310. rc = (*backends[i]->be_unbind)( &pb );
  311. }
  312. slapi_pblock_set( &pb, SLAPI_PLUGIN_OPRETURN, &rc );
  313. (void) plugin_call_plugins( &pb, SLAPI_PLUGIN_POST_UNBIND_FN );
  314. }
  315. }
  316. }
  317. }
  318. int
  319. be_nbackends_public()
  320. {
  321. int i;
  322. int n= 0;
  323. for ( i = 0; i < maxbackends; i++ )
  324. {
  325. if ( backends[i] &&
  326. (backends[i]->be_state != BE_STATE_DELETED) &&
  327. (!backends[i]->be_private) )
  328. {
  329. n++;
  330. }
  331. }
  332. return n;
  333. }
  334. /* backend instance management */
  335. void
  336. slapi_be_Rlock(Slapi_Backend * be)
  337. {
  338. slapi_rwlock_rdlock(be->be_lock);
  339. }
  340. void
  341. slapi_be_Wlock(Slapi_Backend * be)
  342. {
  343. slapi_rwlock_wrlock(be->be_lock);
  344. }
  345. void
  346. slapi_be_Unlock(Slapi_Backend * be)
  347. {
  348. slapi_rwlock_unlock(be->be_lock);
  349. }
  350. /*
  351. * lookup instance names by suffix.
  352. * if isexact == 0: returns instances including ones that associates with
  353. * its sub suffixes.
  354. * e.g., suffix: "o=<suffix>" is given, these are returned:
  355. * suffixes: o=<suffix>, ou=<ou>,o=<suffix>, ...
  356. * instances: inst of "o=<suffix>",
  357. * inst of "ou=<ou>,o=<suffix>",
  358. * ...
  359. * if isexact != 0: returns an instance that associates with the given suffix
  360. * e.g., suffix: "o=<suffix>" is given, these are returned:
  361. * suffixes: "o=<suffix>"
  362. * instances: inst of "o=<suffix>"
  363. * Note: if suffixes
  364. */
  365. int
  366. slapi_lookup_instance_name_by_suffix(char *suffix,
  367. char ***suffixes, char ***instances, int isexact)
  368. {
  369. Slapi_Backend *be = NULL;
  370. struct suffixlist *list;
  371. char *cookie = NULL;
  372. const char *thisdn;
  373. int thisdnlen;
  374. int suffixlen;
  375. int count;
  376. int i;
  377. int rval = -1;
  378. if (instances == NULL)
  379. return rval;
  380. PR_ASSERT(suffix);
  381. rval = 0;
  382. suffixlen = strlen(suffix);
  383. cookie = NULL;
  384. be = slapi_get_first_backend (&cookie);
  385. while (be) {
  386. if (NULL == be->be_suffixlist) {
  387. be = (backend *)slapi_get_next_backend (cookie);
  388. continue;
  389. }
  390. count = slapi_counter_get_value(be->be_suffixcounter);
  391. list = be->be_suffixlist;
  392. for (i = 0; list && i < count; i++) {
  393. thisdn = slapi_sdn_get_ndn(list->be_suffix);
  394. thisdnlen = slapi_sdn_get_ndn_len(list->be_suffix);
  395. if (isexact?suffixlen!=thisdnlen:suffixlen>thisdnlen){
  396. list = list->next;
  397. continue;
  398. }
  399. if (isexact?(!slapi_UTF8CASECMP(suffix, (char *)thisdn)):
  400. (!slapi_UTF8CASECMP(suffix, (char *)thisdn+thisdnlen-suffixlen)))
  401. {
  402. charray_add(instances, slapi_ch_strdup(be->be_name));
  403. if (suffixes)
  404. charray_add(suffixes, slapi_ch_strdup(thisdn));
  405. }
  406. list = list->next;
  407. }
  408. be = (backend *)slapi_get_next_backend (cookie);
  409. }
  410. slapi_ch_free((void **)&cookie);
  411. return rval;
  412. }
  413. /*
  414. * lookup instance names by included suffixes and excluded suffixes.
  415. *
  416. * Get instance names associated with the given included suffixes
  417. * as well as the excluded suffixes.
  418. * Subtract the excluded instances from the included instance.
  419. * Assign the result to instances.
  420. */
  421. int
  422. slapi_lookup_instance_name_by_suffixes(char **included, char **excluded,
  423. char ***instances)
  424. {
  425. char **incl_instances, **excl_instances;
  426. char **p;
  427. int rval = -1;
  428. if (instances == NULL)
  429. return rval;
  430. *instances = NULL;
  431. incl_instances = NULL;
  432. for (p = included; p && *p; p++) {
  433. if (slapi_lookup_instance_name_by_suffix(*p, NULL, &incl_instances, 0)
  434. < 0)
  435. return rval;
  436. }
  437. excl_instances = NULL;
  438. for (p = excluded; p && *p; p++) {
  439. /* okay to be empty */
  440. slapi_lookup_instance_name_by_suffix(*p, NULL, &excl_instances, 0);
  441. }
  442. rval = 0;
  443. if (excl_instances) {
  444. charray_subtract(incl_instances, excl_instances, NULL);
  445. charray_free(excl_instances);
  446. }
  447. *instances = incl_instances;
  448. return rval;
  449. }