cos.c 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  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. #include <stdio.h>
  13. #include <string.h>
  14. #include "portable.h"
  15. #include "nspr.h"
  16. #include "slapi-plugin.h"
  17. #include "slapi-private.h"
  18. #include "cos_cache.h"
  19. #include "vattr_spi.h"
  20. #include <sys/stat.h>
  21. /*** secret slapd stuff ***/
  22. /*
  23. these are required here because they are not available
  24. in any public header. They must exactly match their
  25. counterparts in the server or they will fail to work
  26. correctly.
  27. */
  28. /*** from proto-slap.h ***/
  29. int slapd_log_error_proc(int sev_level, char *subsystem, char *fmt, ...);
  30. /*** end secrets ***/
  31. #define COS_PLUGIN_SUBSYSTEM "cos-plugin" /* used for logging */
  32. /* subrelease in the following version info is for odd-ball cos releases
  33. * which do not fit into a general release, this can be used for beta releases
  34. * and other (this version stuff is really to help outside applications which
  35. * may wish to update cos decide whether the cos version they want to update to
  36. * is a higher release than the installed plugin)
  37. *
  38. * note: release origin is 00 for directory server
  39. * sub-release should be:
  40. * 50 for initial RTM products
  41. * from 0 increasing for alpha/beta releases
  42. * from 51 increasing for patch releases
  43. */
  44. #define COS_VERSION 0x00050050 /* version format: 0x release origin 00 major 05 minor 00 sub-release 00 */
  45. /* other function prototypes */
  46. int cos_init(Slapi_PBlock *pb);
  47. int cos_compute(computed_attr_context *c, char *type, Slapi_Entry *e, slapi_compute_output_t outputfn);
  48. int cos_start(Slapi_PBlock *pb);
  49. int cos_close(Slapi_PBlock *pb);
  50. int cos_post_op(Slapi_PBlock *pb);
  51. static Slapi_PluginDesc pdesc = {"cos", VENDOR, DS_PACKAGE_VERSION,
  52. "class of service plugin"};
  53. static void *cos_plugin_identity = NULL;
  54. /*
  55. ** Plugin identity mgmt
  56. */
  57. void
  58. cos_set_plugin_identity(void *identity)
  59. {
  60. cos_plugin_identity = identity;
  61. }
  62. void *
  63. cos_get_plugin_identity(void)
  64. {
  65. return cos_plugin_identity;
  66. }
  67. int
  68. cos_version(void)
  69. {
  70. return COS_VERSION;
  71. }
  72. /*
  73. * cos_postop_init: registering cos_post_op
  74. * cos_post_op just calls cos_cache_change_notify, which does not have any
  75. * backend operations. Thus, no need to be in transaction. Rather, it is
  76. * harmful if putting in the transaction since tring to hold change_lock
  77. * inside of transaction would cause a deadlock.
  78. */
  79. int
  80. cos_postop_init(Slapi_PBlock *pb)
  81. {
  82. int rc = 0;
  83. if (slapi_pblock_set(pb, SLAPI_PLUGIN_VERSION, SLAPI_PLUGIN_VERSION_01) != 0 ||
  84. slapi_pblock_set(pb, SLAPI_PLUGIN_POST_ADD_FN, (void *)cos_post_op) != 0 ||
  85. slapi_pblock_set(pb, SLAPI_PLUGIN_POST_DELETE_FN, (void *)cos_post_op) != 0 ||
  86. slapi_pblock_set(pb, SLAPI_PLUGIN_POST_MODIFY_FN, (void *)cos_post_op) != 0 ||
  87. slapi_pblock_set(pb, SLAPI_PLUGIN_POST_MODRDN_FN, (void *)cos_post_op) != 0) {
  88. slapi_log_err(SLAPI_LOG_ERR, COS_PLUGIN_SUBSYSTEM,
  89. "cos_postop_init - Failed to register plugin\n");
  90. rc = -1;
  91. }
  92. return rc;
  93. }
  94. int
  95. cos_internalpostop_init(Slapi_PBlock *pb)
  96. {
  97. int rc = 0;
  98. if (slapi_pblock_set(pb, SLAPI_PLUGIN_VERSION,
  99. SLAPI_PLUGIN_VERSION_01) != 0 ||
  100. slapi_pblock_set(pb, SLAPI_PLUGIN_INTERNAL_POST_MODIFY_FN,
  101. (void *)cos_post_op) != 0 ||
  102. slapi_pblock_set(pb, SLAPI_PLUGIN_INTERNAL_POST_MODRDN_FN,
  103. (void *)cos_post_op) != 0 ||
  104. slapi_pblock_set(pb, SLAPI_PLUGIN_INTERNAL_POST_ADD_FN,
  105. (void *)cos_post_op) != 0 ||
  106. slapi_pblock_set(pb, SLAPI_PLUGIN_INTERNAL_POST_DELETE_FN,
  107. (void *)cos_post_op) != 0) {
  108. slapi_log_err(SLAPI_LOG_ERR, COS_PLUGIN_SUBSYSTEM,
  109. "cos_internalpostop_init - Failed to register plugin\n");
  110. rc = -1;
  111. }
  112. return rc;
  113. }
  114. /*
  115. cos_init
  116. --------
  117. adds our callbacks to the list
  118. */
  119. int
  120. cos_init(Slapi_PBlock *pb)
  121. {
  122. int ret = 0;
  123. void *plugin_identity = NULL;
  124. slapi_log_err(SLAPI_LOG_TRACE, COS_PLUGIN_SUBSYSTEM, "--> cos_init\n");
  125. /*
  126. ** Store the plugin identity for later use.
  127. ** Used for internal operations
  128. */
  129. slapi_pblock_get(pb, SLAPI_PLUGIN_IDENTITY, &plugin_identity);
  130. PR_ASSERT(plugin_identity);
  131. cos_set_plugin_identity(plugin_identity);
  132. if (slapi_pblock_set(pb, SLAPI_PLUGIN_VERSION, SLAPI_PLUGIN_VERSION_01) != 0 ||
  133. slapi_pblock_set(pb, SLAPI_PLUGIN_START_FN, (void *)cos_start) != 0 ||
  134. slapi_pblock_set(pb, SLAPI_PLUGIN_CLOSE_FN, (void *)cos_close) != 0 ||
  135. slapi_pblock_set(pb, SLAPI_PLUGIN_DESCRIPTION, (void *)&pdesc) != 0) {
  136. slapi_log_err(SLAPI_LOG_ERR, COS_PLUGIN_SUBSYSTEM,
  137. "cos_init - Failed to register plugin\n");
  138. ret = -1;
  139. goto bailout;
  140. }
  141. ret = slapi_register_plugin("postoperation", 1 /* Enabled */,
  142. "cos_postop_init", cos_postop_init,
  143. "Class of Service postoperation plugin", NULL,
  144. plugin_identity);
  145. if (ret < 0) {
  146. goto bailout;
  147. }
  148. ret = slapi_register_plugin("internalpostoperation", 1 /* Enabled */,
  149. "cos_internalpostop_init", cos_internalpostop_init,
  150. "Class of Service internalpostoperation plugin", NULL,
  151. plugin_identity);
  152. bailout:
  153. slapi_log_err(SLAPI_LOG_TRACE, COS_PLUGIN_SUBSYSTEM, "<-- cos_init\n");
  154. return ret;
  155. }
  156. /*
  157. cos_start
  158. ---------
  159. This function registers the computed attribute evaluator
  160. and inits the cos cache.
  161. It is called after cos_init.
  162. */
  163. int
  164. cos_start(Slapi_PBlock *pb __attribute__((unused)))
  165. {
  166. int ret = 0;
  167. slapi_log_err(SLAPI_LOG_TRACE, COS_PLUGIN_SUBSYSTEM, "--> cos_start\n");
  168. if (!cos_cache_init()) {
  169. slapi_log_err(SLAPI_LOG_PLUGIN, COS_PLUGIN_SUBSYSTEM, "cos_start - Ready for service\n");
  170. } else {
  171. /* problems we are hosed */
  172. cos_cache_stop();
  173. slapi_log_err(SLAPI_LOG_ERR, COS_PLUGIN_SUBSYSTEM, "cos_start - Failed to initialise\n");
  174. ret = -1;
  175. }
  176. slapi_log_err(SLAPI_LOG_TRACE, COS_PLUGIN_SUBSYSTEM, "<-- cos_start\n");
  177. return ret;
  178. }
  179. /*
  180. cos_close
  181. ---------
  182. closes down the cache
  183. */
  184. int
  185. cos_close(Slapi_PBlock *pb __attribute__((unused)))
  186. {
  187. slapi_log_err(SLAPI_LOG_TRACE, COS_PLUGIN_SUBSYSTEM, "--> cos_close\n");
  188. cos_cache_stop();
  189. slapi_log_err(SLAPI_LOG_TRACE, COS_PLUGIN_SUBSYSTEM, "<-- cos_close\n");
  190. return 0;
  191. }
  192. /*
  193. cos_compute
  194. -----------
  195. called when evaluating named attributes in a search
  196. and attributes remain unfound in the entry,
  197. this function checks the attribute for a match with
  198. those in the class of service definitions, and if a
  199. match is found, adds the attribute and value to the
  200. output list
  201. returns
  202. 0 on success
  203. 1 on outright failure
  204. -1 when doesn't know about attribute
  205. */
  206. int
  207. cos_compute(computed_attr_context *c __attribute__((unused)),
  208. char *type __attribute__((unused)),
  209. Slapi_Entry *e __attribute__((unused)),
  210. slapi_compute_output_t outputfn __attribute__((unused)))
  211. {
  212. int ret = -1;
  213. return ret;
  214. }
  215. /*
  216. cos_post_op
  217. -----------
  218. Catch all for all post operations that change entries
  219. in some way - this simply notifies the cache of a
  220. change - the cache decides if action is necessary
  221. */
  222. int
  223. cos_post_op(Slapi_PBlock *pb)
  224. {
  225. slapi_log_err(SLAPI_LOG_TRACE, COS_PLUGIN_SUBSYSTEM, "--> cos_post_op\n");
  226. cos_cache_change_notify(pb);
  227. slapi_log_err(SLAPI_LOG_TRACE, COS_PLUGIN_SUBSYSTEM, "<-- cos_post_op\n");
  228. return SLAPI_PLUGIN_SUCCESS; /* always succeed */
  229. }