cos.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379
  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. Slapi_Entry *plugin_entry = NULL;
  145. char *plugin_type = NULL;
  146. int postadd = SLAPI_PLUGIN_POST_ADD_FN;
  147. int postmod = SLAPI_PLUGIN_POST_MODIFY_FN;
  148. int postmdn = SLAPI_PLUGIN_POST_MODRDN_FN;
  149. int postdel = SLAPI_PLUGIN_POST_DELETE_FN;
  150. if ((slapi_pblock_get(pb, SLAPI_PLUGIN_CONFIG_ENTRY, &plugin_entry) == 0) &&
  151. plugin_entry &&
  152. (plugin_type = slapi_entry_attr_get_charptr(plugin_entry, "nsslapd-plugintype")) &&
  153. plugin_type && strstr(plugin_type, "betxn")) {
  154. postadd = SLAPI_PLUGIN_BE_TXN_POST_ADD_FN;
  155. postmod = SLAPI_PLUGIN_BE_TXN_POST_MODIFY_FN;
  156. postmdn = SLAPI_PLUGIN_BE_TXN_POST_MODRDN_FN;
  157. postdel = SLAPI_PLUGIN_BE_TXN_POST_DELETE_FN;
  158. }
  159. slapi_ch_free_string(&plugin_type);
  160. if ( slapi_pblock_set( pb, SLAPI_PLUGIN_VERSION,
  161. SLAPI_PLUGIN_VERSION_01 ) != 0 ||
  162. slapi_pblock_set(pb, postmod, (void *)cos_post_op ) != 0 ||
  163. slapi_pblock_set(pb, postmdn, (void *)cos_post_op ) != 0 ||
  164. slapi_pblock_set(pb, postadd, (void *) cos_post_op ) != 0 ||
  165. slapi_pblock_set(pb, postdel, (void *) cos_post_op ) != 0 )
  166. {
  167. slapi_log_error( SLAPI_LOG_FATAL, COS_PLUGIN_SUBSYSTEM,
  168. "cos_postop_init: failed to register plugin\n" );
  169. rc = -1;
  170. }
  171. return rc;
  172. }
  173. int
  174. cos_internalpostop_init ( Slapi_PBlock *pb )
  175. {
  176. int rc = 0;
  177. if ( slapi_pblock_set( pb, SLAPI_PLUGIN_VERSION,
  178. SLAPI_PLUGIN_VERSION_01 ) != 0 ||
  179. slapi_pblock_set(pb, SLAPI_PLUGIN_INTERNAL_POST_MODIFY_FN,
  180. (void *)cos_post_op ) != 0 ||
  181. slapi_pblock_set(pb, SLAPI_PLUGIN_INTERNAL_POST_MODRDN_FN,
  182. (void *)cos_post_op ) != 0 ||
  183. slapi_pblock_set(pb, SLAPI_PLUGIN_INTERNAL_POST_ADD_FN,
  184. (void *) cos_post_op ) != 0 ||
  185. slapi_pblock_set(pb, SLAPI_PLUGIN_INTERNAL_POST_DELETE_FN,
  186. (void *) cos_post_op ) != 0 )
  187. {
  188. slapi_log_error( SLAPI_LOG_FATAL, COS_PLUGIN_SUBSYSTEM,
  189. "cos_internalpostop_init: failed to register plugin\n" );
  190. rc = -1;
  191. }
  192. return rc;
  193. }
  194. /*
  195. cos_init
  196. --------
  197. adds our callbacks to the list
  198. */
  199. int cos_init( Slapi_PBlock *pb )
  200. {
  201. int ret = 0;
  202. void * plugin_identity=NULL;
  203. Slapi_Entry *plugin_entry = NULL;
  204. int is_betxn = 0;
  205. const char *plugintype = "postoperation";
  206. LDAPDebug( LDAP_DEBUG_TRACE, "--> cos_init\n",0,0,0);
  207. if ((slapi_pblock_get(pb, SLAPI_PLUGIN_CONFIG_ENTRY, &plugin_entry) == 0) &&
  208. plugin_entry) {
  209. is_betxn = slapi_entry_attr_get_bool(plugin_entry, "nsslapd-pluginbetxn");
  210. }
  211. /*
  212. ** Store the plugin identity for later use.
  213. ** Used for internal operations
  214. */
  215. slapi_pblock_get (pb, SLAPI_PLUGIN_IDENTITY, &plugin_identity);
  216. PR_ASSERT (plugin_identity);
  217. cos_set_plugin_identity(plugin_identity);
  218. if ( slapi_pblock_set( pb, SLAPI_PLUGIN_VERSION,
  219. SLAPI_PLUGIN_VERSION_01 ) != 0 ||
  220. slapi_pblock_set(pb, SLAPI_PLUGIN_START_FN,
  221. (void *) cos_start ) != 0 ||
  222. slapi_pblock_set(pb, SLAPI_PLUGIN_CLOSE_FN,
  223. (void *) cos_close ) != 0 ||
  224. slapi_pblock_set( pb, SLAPI_PLUGIN_DESCRIPTION,
  225. (void *)&pdesc ) != 0 )
  226. {
  227. slapi_log_error( SLAPI_LOG_FATAL, COS_PLUGIN_SUBSYSTEM,
  228. "cos_init: failed to register plugin\n" );
  229. ret = -1;
  230. goto bailout;
  231. }
  232. if (is_betxn) {
  233. plugintype = "betxnpostoperation";
  234. }
  235. ret = slapi_register_plugin(plugintype, 1 /* Enabled */,
  236. "cos_postop_init", cos_postop_init,
  237. "Class of Service postoperation plugin", NULL,
  238. plugin_identity);
  239. if ( ret < 0 ) {
  240. goto bailout;
  241. }
  242. if (!is_betxn) {
  243. ret = slapi_register_plugin("internalpostoperation", 1 /* Enabled */,
  244. "cos_internalpostop_init", cos_internalpostop_init,
  245. "Class of Service internalpostoperation plugin", NULL,
  246. plugin_identity);
  247. }
  248. bailout:
  249. LDAPDebug( LDAP_DEBUG_TRACE, "<-- cos_init\n",0,0,0);
  250. return ret;
  251. }
  252. /*
  253. cos_start
  254. ---------
  255. This function registers the computed attribute evaluator
  256. and inits the cos cache.
  257. It is called after cos_init.
  258. */
  259. int cos_start( Slapi_PBlock *pb )
  260. {
  261. int ret = 0;
  262. LDAPDebug( LDAP_DEBUG_TRACE, "--> cos_start\n",0,0,0);
  263. if( !cos_cache_init() )
  264. {
  265. LDAPDebug( LDAP_DEBUG_PLUGIN, "cos: ready for service\n",0,0,0);
  266. }
  267. else
  268. {
  269. /* problems we are hosed */
  270. cos_cache_stop();
  271. LDAPDebug( LDAP_DEBUG_ANY, "cos_start: failed to initialise\n",0,0,0);
  272. ret = -1;
  273. }
  274. LDAPDebug( LDAP_DEBUG_TRACE, "<-- cos_start\n",0,0,0);
  275. return ret;
  276. }
  277. /*
  278. cos_close
  279. ---------
  280. closes down the cache
  281. */
  282. int cos_close( Slapi_PBlock *pb )
  283. {
  284. LDAPDebug( LDAP_DEBUG_TRACE, "--> cos_close\n",0,0,0);
  285. cos_cache_stop();
  286. LDAPDebug( LDAP_DEBUG_TRACE, "<-- cos_close\n",0,0,0);
  287. return 0;
  288. }
  289. /*
  290. cos_compute
  291. -----------
  292. called when evaluating named attributes in a search
  293. and attributes remain unfound in the entry,
  294. this function checks the attribute for a match with
  295. those in the class of service definitions, and if a
  296. match is found, adds the attribute and value to the
  297. output list
  298. returns
  299. 0 on success
  300. 1 on outright failure
  301. -1 when doesn't know about attribute
  302. */
  303. int cos_compute(computed_attr_context *c,char* type,Slapi_Entry *e,slapi_compute_output_t outputfn)
  304. {
  305. int ret = -1;
  306. return ret;
  307. }
  308. /*
  309. cos_post_op
  310. -----------
  311. Catch all for all post operations that change entries
  312. in some way - this simply notifies the cache of a
  313. change - the cache decides if action is necessary
  314. */
  315. int cos_post_op( Slapi_PBlock *pb )
  316. {
  317. LDAPDebug( LDAP_DEBUG_TRACE, "--> cos_post_op\n",0,0,0);
  318. cos_cache_change_notify(pb);
  319. LDAPDebug( LDAP_DEBUG_TRACE, "<-- cos_post_op\n",0,0,0);
  320. return 0; /* always succeed */
  321. }