testpreop.c 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  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. /************************************************************
  39. testpreop.c
  40. This source file provides examples of pre-operation plug-in
  41. functions. The server calls these plug-in functions before
  42. executing certain LDAP operations:
  43. * testpreop_bind (called before an LDAP bind operation)
  44. * testpreop_add (called before an LDAP add operation)
  45. * testpreop_search (called before an LDAP search operation)
  46. * testpreop_abandon (called before an LDAP abandon operation)
  47. testpreop_bind logs information about the LDAP bind operation
  48. to the server error log. testpreop_add prepends the name "BOB"
  49. to the value of the cn attribute before an entry is added.
  50. Note that the Directory Server front-end handles bind
  51. operations requested by the root DN. The server does not
  52. invoke your plug-in function if the client is authenticating
  53. as the root DN.
  54. To test this plug-in function, stop the server, edit the dse.ldif file
  55. (in the <server_root>/slapd-<server_id>/config directory)
  56. and add the following lines before restarting the server :
  57. dn: cn=Test Preop,cn=plugins,cn=config
  58. objectClass: top
  59. objectClass: nsSlapdPlugin
  60. objectClass: extensibleObject
  61. cn: Test Preop
  62. nsslapd-pluginPath: <server_root>/plugins/slapd/slapi/examples/libtest-plugin.so
  63. nsslapd-pluginInitfunc: testpreop_init
  64. nsslapd-pluginType: preoperation
  65. nsslapd-pluginEnabled: on
  66. nsslapd-plugin-depends-on-type: database
  67. nsslapd-pluginId: test-preop
  68. ************************************************************/
  69. #include <stdio.h>
  70. #include <string.h>
  71. #include "slapi-plugin.h"
  72. Slapi_PluginDesc preoppdesc = { "test-preop", "Fedora Project", "1.0.2",
  73. "sample pre-operation plugin" };
  74. /* Pre-operation plug-in function */
  75. int
  76. testpreop_bind( Slapi_PBlock *pb )
  77. {
  78. char *dn;
  79. int method;
  80. char *auth;
  81. /* Get the DN that the client is binding as and the method
  82. of authentication used. */
  83. if ( slapi_pblock_get( pb, SLAPI_BIND_TARGET, &dn ) != 0 ||
  84. slapi_pblock_get( pb, SLAPI_BIND_METHOD, &method ) != 0 ) {
  85. slapi_log_error( SLAPI_LOG_PLUGIN,
  86. "testpreop_bind", "Could not get parameters\n" );
  87. return( -1 );
  88. }
  89. switch( method ) {
  90. case LDAP_AUTH_NONE:
  91. auth = "No authentication";
  92. break;
  93. case LDAP_AUTH_SIMPLE:
  94. auth = "Simple authentication";
  95. break;
  96. case LDAP_AUTH_SASL:
  97. auth = "SASL authentication";
  98. break;
  99. default:
  100. auth = "Unknown method of authentication";
  101. break;
  102. }
  103. /* Log information about the bind operation to the
  104. server error log. */
  105. slapi_log_error( SLAPI_LOG_PLUGIN, "testpreop_bind",
  106. "Preoperation bind function called.\n"
  107. "\tTarget DN: %s\n\tAuthentication method: %s\n",
  108. dn, auth );
  109. return( 0 ); /* allow the operation to continue */
  110. }
  111. /* Pre-operation plug-in function */
  112. int
  113. testpreop_add( Slapi_PBlock *pb )
  114. {
  115. Slapi_Entry *e;
  116. Slapi_Attr *a;
  117. Slapi_Value *v;
  118. struct berval **bvals;
  119. int i, hint;
  120. char *tmp;
  121. const char *s;
  122. /* Get the entry that is about to be added. */
  123. if ( slapi_pblock_get( pb, SLAPI_ADD_ENTRY, &e ) != 0 ) {
  124. slapi_log_error( SLAPI_LOG_PLUGIN,
  125. "testpreop_add", "Could not get entry\n" );
  126. return( -1 );
  127. }
  128. /* Prepend the name "BOB" to the value of the cn attribute
  129. in the entry. */
  130. if ( slapi_entry_attr_find( e, "cn", &a ) == 0 ) {
  131. for ( hint = slapi_attr_first_value( a, &v ); hint != -1;
  132. hint = slapi_attr_next_value( a, hint, &v )) {
  133. s = slapi_value_get_string( v );
  134. tmp = (char *) malloc( 5 + strlen( s ));
  135. strcpy( tmp, "BOB " );
  136. strcat( tmp + 4, s );
  137. slapi_value_set_string( v, tmp );
  138. free( tmp );
  139. }
  140. }
  141. return( 0 ); /* allow the operation to continue */
  142. }
  143. /* Pre-operation plug-in function */
  144. int
  145. testpreop_search( Slapi_PBlock *pb )
  146. {
  147. char *base;
  148. /* Log a message to indicate when the plug-in function starts */
  149. slapi_log_error( SLAPI_LOG_FATAL, "testpreop_search",
  150. "*** PREOPERATION SEARCH PLUGIN ***\n");
  151. /* Get and log the base DN of the search criteria */
  152. if ( slapi_pblock_get( pb, SLAPI_SEARCH_TARGET, &base ) == 0 )
  153. slapi_log_error( SLAPI_LOG_FATAL, "SLAPI_SEARCH_TARGET",
  154. "%s\n", base );
  155. /* Get and log the original base DN */
  156. if ( slapi_pblock_get( pb, SLAPI_ORIGINAL_TARGET_DN, &base ) == 0 )
  157. slapi_log_error( SLAPI_LOG_FATAL, "SLAPI_ORIGINAL_TARGET_DN",
  158. "%s\n", base );
  159. return( 0 ); /* allow the operation to continue */
  160. }
  161. /* Pre-operation plug-in function */
  162. int
  163. testpreop_abandon( Slapi_PBlock *pb )
  164. {
  165. int msgid;
  166. /* Get the LDAP message ID of the abandon target */
  167. if ( slapi_pblock_get( pb, SLAPI_ABANDON_MSGID, &msgid ) != 0 ) {
  168. slapi_log_error( SLAPI_LOG_PLUGIN,
  169. "testpreop_abandon", "Could not get parameters\n" );
  170. return( -1 );
  171. }
  172. /* Log information about the abandon operation to the
  173. server error log. */
  174. slapi_log_error( SLAPI_LOG_PLUGIN, "testpreop_bind",
  175. "Preoperation abandon function called.\n"
  176. "\tTarget MsgID: %d\n",
  177. msgid );
  178. return( 0 ); /* allow the operation to continue */
  179. }
  180. static void
  181. get_plugin_config_dn_and_entry( char *msg, Slapi_PBlock *pb )
  182. {
  183. char *dn = NULL;
  184. Slapi_Entry *e = NULL;
  185. int loglevel = SLAPI_LOG_PLUGIN;
  186. if ( slapi_pblock_get( pb, SLAPI_TARGET_DN, &dn ) != 0 || dn == NULL ) {
  187. slapi_log_error( loglevel, msg, "failed to get plugin config DN\n" );
  188. } else {
  189. slapi_log_error( loglevel, msg, "this plugin's config DN is \"%s\"\n",
  190. dn );
  191. }
  192. if ( slapi_pblock_get( pb, SLAPI_ADD_ENTRY, &e ) != 0 || e == NULL ) {
  193. slapi_log_error( loglevel, msg, "failed to get plugin config entry\n" );
  194. } else {
  195. char *ldif;
  196. ldif = slapi_entry2str_with_options( e, NULL, 0 );
  197. slapi_log_error( loglevel, msg,
  198. "this plugin's config entry is \"\n%s\"\n", ldif );
  199. slapi_ch_free_string( &ldif );
  200. }
  201. }
  202. static int
  203. testpreop_start( Slapi_PBlock *pb )
  204. {
  205. get_plugin_config_dn_and_entry( "testpreop_start", pb );
  206. return( 0 );
  207. }
  208. /* Initialization function */
  209. #ifdef _WIN32
  210. __declspec(dllexport)
  211. #endif
  212. int
  213. testpreop_init( Slapi_PBlock *pb )
  214. {
  215. /* Register the two pre-operation plug-in functions,
  216. and specify the server plug-in version. */
  217. if ( slapi_pblock_set( pb, SLAPI_PLUGIN_VERSION,
  218. SLAPI_PLUGIN_VERSION_01 ) != 0 ||
  219. slapi_pblock_set( pb, SLAPI_PLUGIN_DESCRIPTION,
  220. (void *)&preoppdesc ) != 0 ||
  221. slapi_pblock_set( pb, SLAPI_PLUGIN_START_FN,
  222. (void *) testpreop_start ) != 0 ||
  223. slapi_pblock_set( pb, SLAPI_PLUGIN_PRE_BIND_FN,
  224. (void *) testpreop_bind ) != 0 ||
  225. slapi_pblock_set( pb, SLAPI_PLUGIN_PRE_ADD_FN,
  226. (void *) testpreop_add ) != 0 ||
  227. slapi_pblock_set( pb, SLAPI_PLUGIN_PRE_SEARCH_FN,
  228. (void *) testpreop_search ) != 0 ||
  229. slapi_pblock_set( pb, SLAPI_PLUGIN_PRE_ABANDON_FN,
  230. (void *) testpreop_abandon ) != 0 ) {
  231. slapi_log_error( SLAPI_LOG_FATAL, "testpreop_init",
  232. "Failed to set version and function\n" );
  233. return( -1 );
  234. }
  235. return( 0 );
  236. }