testpreop.c 7.9 KB

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