cos.c 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353
  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 <stdio.h>
  42. #include <string.h>
  43. #include "portable.h"
  44. #include "nspr.h"
  45. #include "slapi-plugin.h"
  46. #include "slapi-private.h"
  47. #include "cos_cache.h"
  48. #include "vattr_spi.h"
  49. /* get file mode flags for unix */
  50. #ifndef _WIN32
  51. #include <sys/stat.h>
  52. #endif
  53. /*** secret slapd stuff ***/
  54. /*
  55. these are required here because they are not available
  56. in any public header. They must exactly match their
  57. counterparts in the server or they will fail to work
  58. correctly.
  59. */
  60. /*** from proto-slap.h ***/
  61. int slapd_log_error_proc( char *subsystem, char *fmt, ... );
  62. /*** from ldaplog.h ***/
  63. /* edited ldaplog.h for LDAPDebug()*/
  64. #ifndef _LDAPLOG_H
  65. #define _LDAPLOG_H
  66. #ifdef __cplusplus
  67. extern "C" {
  68. #endif
  69. #define LDAP_DEBUG_TRACE 0x00001 /* 1 */
  70. #define LDAP_DEBUG_ANY 0x04000 /* 16384 */
  71. #define LDAP_DEBUG_PLUGIN 0x10000 /* 65536 */
  72. /* debugging stuff */
  73. # ifdef _WIN32
  74. extern int *module_ldap_debug;
  75. # define LDAPDebug( level, fmt, arg1, arg2, arg3 ) \
  76. { \
  77. if ( *module_ldap_debug & level ) { \
  78. slapd_log_error_proc( NULL, fmt, arg1, arg2, arg3 ); \
  79. } \
  80. }
  81. # else /* _WIN32 */
  82. extern int slapd_ldap_debug;
  83. # define LDAPDebug( level, fmt, arg1, arg2, arg3 ) \
  84. { \
  85. if ( slapd_ldap_debug & level ) { \
  86. slapd_log_error_proc( NULL, fmt, arg1, arg2, arg3 ); \
  87. } \
  88. }
  89. # endif /* Win32 */
  90. #ifdef __cplusplus
  91. }
  92. #endif
  93. #endif /* _LDAP_H */
  94. /*** end secrets ***/
  95. #define COS_PLUGIN_SUBSYSTEM "cos-plugin" /* used for logging */
  96. /* subrelease in the following version info is for odd-ball cos releases
  97. * which do not fit into a general release, this can be used for beta releases
  98. * and other (this version stuff is really to help outside applications which
  99. * may wish to update cos decide whether the cos version they want to update to
  100. * is a higher release than the installed plugin)
  101. *
  102. * note: release origin is 00 for directory server
  103. * sub-release should be:
  104. * 50 for initial RTM products
  105. * from 0 increasing for alpha/beta releases
  106. * from 51 increasing for patch releases
  107. */
  108. #define COS_VERSION 0x00050050 /* version format: 0x release origin 00 major 05 minor 00 sub-release 00 */
  109. /* other function prototypes */
  110. int cos_init( Slapi_PBlock *pb );
  111. int cos_compute(computed_attr_context *c,char* type,Slapi_Entry *e,slapi_compute_output_t outputfn);
  112. int cos_start( Slapi_PBlock *pb );
  113. int cos_close( Slapi_PBlock *pb );
  114. int cos_post_op( Slapi_PBlock *pb );
  115. static Slapi_PluginDesc pdesc = { "cos", VENDOR, DS_PACKAGE_VERSION,
  116. "class of service plugin" };
  117. static void * cos_plugin_identity = NULL;
  118. #ifdef _WIN32
  119. int *module_ldap_debug = 0;
  120. void plugin_init_debug_level(int *level_ptr)
  121. {
  122. module_ldap_debug = level_ptr;
  123. }
  124. #endif
  125. /*
  126. ** Plugin identity mgmt
  127. */
  128. void cos_set_plugin_identity(void * identity)
  129. {
  130. cos_plugin_identity=identity;
  131. }
  132. void * cos_get_plugin_identity()
  133. {
  134. return cos_plugin_identity;
  135. }
  136. int cos_version()
  137. {
  138. return COS_VERSION;
  139. }
  140. int
  141. cos_postop_init ( Slapi_PBlock *pb )
  142. {
  143. int rc = 0;
  144. if ( slapi_pblock_set( pb, SLAPI_PLUGIN_VERSION,
  145. SLAPI_PLUGIN_VERSION_01 ) != 0 ||
  146. slapi_pblock_set(pb, SLAPI_PLUGIN_POST_MODIFY_FN,
  147. (void *)cos_post_op ) != 0 ||
  148. slapi_pblock_set(pb, SLAPI_PLUGIN_POST_MODRDN_FN,
  149. (void *)cos_post_op ) != 0 ||
  150. slapi_pblock_set(pb, SLAPI_PLUGIN_POST_ADD_FN,
  151. (void *) cos_post_op ) != 0 ||
  152. slapi_pblock_set(pb, SLAPI_PLUGIN_POST_DELETE_FN,
  153. (void *) cos_post_op ) != 0 )
  154. {
  155. slapi_log_error( SLAPI_LOG_FATAL, COS_PLUGIN_SUBSYSTEM,
  156. "cos_postop_init: failed to register plugin\n" );
  157. rc = -1;
  158. }
  159. return rc;
  160. }
  161. int
  162. cos_internalpostop_init ( Slapi_PBlock *pb )
  163. {
  164. int rc = 0;
  165. if ( slapi_pblock_set( pb, SLAPI_PLUGIN_VERSION,
  166. SLAPI_PLUGIN_VERSION_01 ) != 0 ||
  167. slapi_pblock_set(pb, SLAPI_PLUGIN_INTERNAL_POST_MODIFY_FN,
  168. (void *)cos_post_op ) != 0 ||
  169. slapi_pblock_set(pb, SLAPI_PLUGIN_INTERNAL_POST_MODRDN_FN,
  170. (void *)cos_post_op ) != 0 ||
  171. slapi_pblock_set(pb, SLAPI_PLUGIN_INTERNAL_POST_ADD_FN,
  172. (void *) cos_post_op ) != 0 ||
  173. slapi_pblock_set(pb, SLAPI_PLUGIN_INTERNAL_POST_DELETE_FN,
  174. (void *) cos_post_op ) != 0 )
  175. {
  176. slapi_log_error( SLAPI_LOG_FATAL, COS_PLUGIN_SUBSYSTEM,
  177. "cos_internalpostop_init: failed to register plugin\n" );
  178. rc = -1;
  179. }
  180. return rc;
  181. }
  182. /*
  183. cos_init
  184. --------
  185. adds our callbacks to the list
  186. */
  187. int cos_init( Slapi_PBlock *pb )
  188. {
  189. int ret = 0;
  190. void * plugin_identity=NULL;
  191. LDAPDebug( LDAP_DEBUG_TRACE, "--> cos_init\n",0,0,0);
  192. /*
  193. ** Store the plugin identity for later use.
  194. ** Used for internal operations
  195. */
  196. slapi_pblock_get (pb, SLAPI_PLUGIN_IDENTITY, &plugin_identity);
  197. PR_ASSERT (plugin_identity);
  198. cos_set_plugin_identity(plugin_identity);
  199. if ( slapi_pblock_set( pb, SLAPI_PLUGIN_VERSION,
  200. SLAPI_PLUGIN_VERSION_01 ) != 0 ||
  201. slapi_pblock_set(pb, SLAPI_PLUGIN_START_FN,
  202. (void *) cos_start ) != 0 ||
  203. slapi_pblock_set(pb, SLAPI_PLUGIN_CLOSE_FN,
  204. (void *) cos_close ) != 0 ||
  205. slapi_pblock_set( pb, SLAPI_PLUGIN_DESCRIPTION,
  206. (void *)&pdesc ) != 0 )
  207. {
  208. slapi_log_error( SLAPI_LOG_FATAL, COS_PLUGIN_SUBSYSTEM,
  209. "cos_init: failed to register plugin\n" );
  210. ret = -1;
  211. goto bailout;
  212. }
  213. ret = slapi_register_plugin("postoperation", 1 /* Enabled */,
  214. "cos_postop_init", cos_postop_init,
  215. "Class of Service postoperation plugin", NULL,
  216. plugin_identity);
  217. if ( ret < 0 ) {
  218. goto bailout;
  219. }
  220. ret = slapi_register_plugin("internalpostoperation", 1 /* Enabled */,
  221. "cos_internalpostop_init", cos_internalpostop_init,
  222. "Class of Service internalpostoperation plugin", NULL,
  223. plugin_identity);
  224. bailout:
  225. LDAPDebug( LDAP_DEBUG_TRACE, "<-- cos_init\n",0,0,0);
  226. return ret;
  227. }
  228. /*
  229. cos_start
  230. ---------
  231. This function registers the computed attribute evaluator
  232. and inits the cos cache.
  233. It is called after cos_init.
  234. */
  235. int cos_start( Slapi_PBlock *pb )
  236. {
  237. int ret = 0;
  238. LDAPDebug( LDAP_DEBUG_TRACE, "--> cos_start\n",0,0,0);
  239. if( !cos_cache_init() )
  240. {
  241. LDAPDebug( LDAP_DEBUG_PLUGIN, "cos: ready for service\n",0,0,0);
  242. }
  243. else
  244. {
  245. /* problems we are hosed */
  246. cos_cache_stop();
  247. LDAPDebug( LDAP_DEBUG_ANY, "cos_start: failed to initialise\n",0,0,0);
  248. ret = -1;
  249. }
  250. LDAPDebug( LDAP_DEBUG_TRACE, "<-- cos_start\n",0,0,0);
  251. return ret;
  252. }
  253. /*
  254. cos_close
  255. ---------
  256. closes down the cache
  257. */
  258. int cos_close( Slapi_PBlock *pb )
  259. {
  260. LDAPDebug( LDAP_DEBUG_TRACE, "--> cos_close\n",0,0,0);
  261. cos_cache_stop();
  262. LDAPDebug( LDAP_DEBUG_TRACE, "<-- cos_close\n",0,0,0);
  263. return 0;
  264. }
  265. /*
  266. cos_compute
  267. -----------
  268. called when evaluating named attributes in a search
  269. and attributes remain unfound in the entry,
  270. this function checks the attribute for a match with
  271. those in the class of service definitions, and if a
  272. match is found, adds the attribute and value to the
  273. output list
  274. returns
  275. 0 on success
  276. 1 on outright failure
  277. -1 when doesn't know about attribute
  278. */
  279. int cos_compute(computed_attr_context *c,char* type,Slapi_Entry *e,slapi_compute_output_t outputfn)
  280. {
  281. int ret = -1;
  282. return ret;
  283. }
  284. /*
  285. cos_post_op
  286. -----------
  287. Catch all for all post operations that change entries
  288. in some way - this simply notifies the cache of a
  289. change - the cache decides if action is necessary
  290. */
  291. int cos_post_op( Slapi_PBlock *pb )
  292. {
  293. LDAPDebug( LDAP_DEBUG_TRACE, "--> cos_post_op\n",0,0,0);
  294. cos_cache_change_notify(pb);
  295. LDAPDebug( LDAP_DEBUG_TRACE, "<-- cos_post_op\n",0,0,0);
  296. return 0; /* always succeed */
  297. }