summaryrefslogtreecommitdiffstats
path: root/ldap/servers/slapd/test-plugins
diff options
context:
space:
mode:
authorNoriko Hosoi <nhosoi@redhat.com>2006-12-15 00:22:54 +0000
committerNoriko Hosoi <nhosoi@redhat.com>2006-12-15 00:22:54 +0000
commit38c192bb2279e1a099b1ec1b6e8eeea24b3fca58 (patch)
tree2d44e32e4eefc00ac431acaf0854c319fa31ed65 /ldap/servers/slapd/test-plugins
parentb05e86a1004cccbe0573b3268b7c8a428323967e (diff)
downloadds-38c192bb2279e1a099b1ec1b6e8eeea24b3fca58.tar.gz
ds-38c192bb2279e1a099b1ec1b6e8eeea24b3fca58.tar.xz
ds-38c192bb2279e1a099b1ec1b6e8eeea24b3fca58.zip
Resolves: #195305
Summary: make new_task() non-static Adding a sample task plugin code and updating the README for the plugin.
Diffstat (limited to 'ldap/servers/slapd/test-plugins')
-rw-r--r--ldap/servers/slapd/test-plugins/README59
-rw-r--r--ldap/servers/slapd/test-plugins/sampletask.c242
2 files changed, 291 insertions, 10 deletions
diff --git a/ldap/servers/slapd/test-plugins/README b/ldap/servers/slapd/test-plugins/README
index 6964e0fc..dd890347 100644
--- a/ldap/servers/slapd/test-plugins/README
+++ b/ldap/servers/slapd/test-plugins/README
@@ -87,6 +87,12 @@ testsaslbind.c
This is an example of a pre-operation plug-in function that
implements a SASL mechanism.
+sampletask.c
+------------
+This is an example of task plug-in that implements a task which is
+invoked by adding the corresponding task entry.
+
+
clients
-------
This directory contains the C and Java source code for clients
@@ -109,7 +115,7 @@ Server plug-ins are built as libraries available to the server.
1. Include the Plug-In API. For example:
- #include "[serverRoot]/plugins/slapd/slapi/include/slapi-plugin.h"
+ #include "slapi-plugin.h"
2. Write your plug-in, including a top level initialization function
used by the server to start the plug-in. For example:
@@ -133,14 +139,47 @@ Server plug-ins are built as libraries available to the server.
} /* my_plugin_init() */
- See the Parameter Block Reference in the Netscape Directory Server
+ See the Parameter Block Reference in the Red Hat Directory Server
Plug-In Programmer's Guide for hints on plug-in types.
3. Build the plug-in as a library.
- We recommend you copy and adapt the Makefile in
- [serverRoot]/plugins/slapd/slapi/examples.
-
+ We recommend to use the Directory Server's build scheme.
+ 3.1 Add your plugin to Makefile.am
+ Index: Makefile.am
+ ===================================================================
+ RCS file: /cvs/dirsec/ldapserver/Makefile.am,v
+ retrieving revision 1.14
+ diff -t -w -U2 -r1.14 Makefile.am
+ --- Makefile.am 16 Nov 2006 18:56:03 -0000 1.14
+ +++ Makefile.am 14 Dec 2006 23:51:30 -0000
+ @@ -74,5 +74,5 @@
+
+ serverplugin_LTLIBRARIES = libacl-plugin.la libattr-unique-plugin.la libchainingdb-plugin.la \
+ - libcos-plugin.la libdes-plugin.la libdistrib-plugin.la \
+ + libsampletask-plugin.la libcos-plugin.la libdes-plugin.la libdistrib-plugin.la \
+ libhttp-client-plugin.la libcollation-plugin.la libpam-passthru-plugin.la \
+ libpassthru-plugin.la libpresence-plugin.la libpwdstorage-plugin.la \
+ @@ -540,4 +540,11 @@
+
+ #------------------------
+ +# libsampletask-plugin
+ +#------------------------
+ +libsampletask_plugin_la_SOURCES = ldap/servers/slapd/test-plugins/sampletask.c
+ +
+ +libsampletask_plugin_la_CPPFLAGS = $(PLUGIN_CPPFLAGS)
+ +
+ +#------------------------
+ # libdes-plugin
+ #-----------------------
+
+ 3.2 run autotool commands/configure
+ $ cd <src_root>/ldapserver
+ $ autogen.sh # make sure there is no errors / warnings
+ $ mkdir testbuild
+ $ cd testbuild
+ $ ../configure --with-fhs [ --prefix=/opt/fedora-ds ... ]
+ $ make install
Plugging the Library Into the Server
------------------------------------
@@ -149,17 +188,17 @@ When started, the server loads plug-ins.
1. Stop the server.
Console: Select the server; Object > Stop Server
- Command Line: cd [serverRoot]/slapd-[serverID] ; ./stop-slapd
+ Command Line: cd [prefix]/usr/lib/<brand>-ds/slapd-[serverID] ; ./stop-slapd
2. Add the entry for the server plug-in to
- [serverRoot]/slapd-[serverID]/config/dse.ldif. For example:
+ [prefix]/var/lib/slapd-[serverID]/dse.ldif. For example:
dn: cn=[My Server Plugin],cn=plugins,cn=config
objectClass: top
objectClass: nsSlapdPlugin
objectClass: extensibleObject
cn: [My Server Plugin]
- nsslapd-pluginPath: [[serverRoot]/myPlugins/myveryown-plugin.so]
+ nsslapd-pluginPath: [[prefix]/usr/lib/<brand>-ds/plugins/myveryown-plugin.so]
nsslapd-pluginInitfunc: [my_plugin_init]
nsslapd-pluginType: [myPluginType]
nsslapd-pluginEnabled: on
@@ -172,10 +211,10 @@ When started, the server loads plug-ins.
nsslapd-pluginVendor: [Fictional Software Company Incorporated]
nsslapd-pluginDescription: [Add lots of cool functionality]
- See the Parameter Block Reference in the Netscape Directory Server
+ See the Parameter Block Reference in the Red Hat Directory Server
Plug-In Programmer's Guide for hints on plug-in types.
3. Restart the server.
Console: Object > Start Server
- Command Line: cd [serverRoot]/slapd-[serverID] ; ./restart-slapd
+ Command Line: cd [prefix]/usr/lib/<brand>-ds/slapd-[serverID] ; ./restart-slapd
diff --git a/ldap/servers/slapd/test-plugins/sampletask.c b/ldap/servers/slapd/test-plugins/sampletask.c
new file mode 100644
index 00000000..88fe6f39
--- /dev/null
+++ b/ldap/servers/slapd/test-plugins/sampletask.c
@@ -0,0 +1,242 @@
+/** BEGIN COPYRIGHT BLOCK
+ * This Program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation; version 2 of the License.
+ *
+ * This Program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this Program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * In addition, as a special exception, Red Hat, Inc. gives You the additional
+ * right to link the code of this Program with code not covered under the GNU
+ * General Public License ("Non-GPL Code") and to distribute linked combinations
+ * including the two, subject to the limitations in this paragraph. Non-GPL Code
+ * permitted under this exception must only link to the code of this Program
+ * through those well defined interfaces identified in the file named EXCEPTION
+ * found in the source code files (the "Approved Interfaces"). The files of
+ * Non-GPL Code may instantiate templates or use macros or inline functions from
+ * the Approved Interfaces without causing the resulting work to be covered by
+ * the GNU General Public License. Only Red Hat, Inc. may make changes or
+ * additions to the list of Approved Interfaces. You must obey the GNU General
+ * Public License in all respects for all of the Program code and other code used
+ * in conjunction with the Program except the Non-GPL Code covered by this
+ * exception. If you modify this file, you may extend this exception to your
+ * version of the file, but you are not obligated to do so. If you do not wish to
+ * provide this exception without modification, you must delete this exception
+ * statement from your version and license this file solely under the GPL without
+ * exception.
+ *
+ * Copyright (C) 2006 Red Hat, Inc.
+ * All rights reserved.
+ * END COPYRIGHT BLOCK **/
+
+/*
+ * sample task plugin
+ *
+ * [How to set up the plugin for testing]
+ * 1. compile and package with the other plugins
+ * 2. put the plugin libsampletask-plugin.so at <prefix>/usr/lib/<brand>-ds/plugins
+ * 3. register it as a plugin in dse.ldif
+ * Plugin entry:
+ * dn: cn=sampletask,cn=plugins,cn=config
+ * objectClass: top
+ * objectClass: nsSlapdPlugin
+ * objectClass: extensibleObject
+ * cn: sampletask
+ * nsslapd-pluginPath: <prefix>/usr/lib/<brand>-ds/plugins/libsampletask-plugin.so
+ * nsslapd-pluginInitfunc: sampletask_init
+ * nsslapd-pluginType: object
+ * nsslapd-pluginEnabled: on
+ * nsslapd-pluginId: sampletask
+ * nsslapd-pluginVersion: <plugin_version>
+ * nsslapd-pluginVendor: <vendor name>
+ * nsslapd-pluginDescription: Sample task plugin
+ *
+ * 4. create a config task entry in dse.ldif
+ * Task entry:
+ * dn: cn=sample task, cn=tasks, cn=config
+ * objectClass: top
+ * objectClass: extensibleObject
+ * cn: sample task
+ *
+ * 5. to invoke the sample task, run the command line:
+ * $ ./ldapmodify -h <host> -p <port> -D "cn=Directory Manager" -w <pw> -a
+ * dn: cn=sample task 0, cn=sample task, cn=tasks, cn=config
+ * objectClass: top
+ * objectClass: extensibleObject
+ * cn: sample task 0
+ * arg0: sample task arg0
+ *
+ * Result is in the errors log
+ * [...] - Sample task starts (arg: sample task arg0) ...
+ * [...] - Sample task finished.
+ */
+
+#include "slap.h"
+#include "slapi-private.h"
+
+static int task_sampletask_add(Slapi_PBlock *pb, Slapi_Entry *e,
+ Slapi_Entry *eAfter, int *returncode, char *returntext,
+ void *arg);
+static int task_sampletask_start(Slapi_PBlock *pb);
+
+/*
+ * Init function
+ * Specified in the plugin entry as "nsslapd-pluginInitfunc: sampletask_init"
+ */
+int
+sampletask_init( Slapi_PBlock *pb )
+{
+ int rc = 0;
+ rc = slapi_pblock_set( pb, SLAPI_PLUGIN_VERSION,
+ (void *) SLAPI_PLUGIN_VERSION_03 );
+ rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_START_FN,
+ (void *) task_sampletask_start );
+
+ return rc;
+}
+
+/*
+ * Task start function
+ * Register the function task_sampletask_add, which invokes the task on demand.
+ */
+static int
+task_sampletask_start(Slapi_PBlock *pb)
+{
+ int rc = slapi_task_register_handler("sample task", task_sampletask_add);
+ return rc;
+}
+
+/*
+ * Task thread
+ * Not necessary be a thread, but it'd not disturb the server's other jobs.
+ */
+static void
+task_sampletask_thread(void *arg)
+{
+ Slapi_PBlock *pb = (Slapi_PBlock *)arg;
+ Slapi_Task *task = pb->pb_task;
+ int rv;
+
+ task->task_work = 1;
+ task->task_progress = 0;
+ task->task_state = SLAPI_TASK_RUNNING;
+ slapi_task_status_changed(task);
+
+ slapi_task_log_notice(task, "Sample task starts (arg: %s) ...\n",
+ pb->pb_seq_val);
+ LDAPDebug(LDAP_DEBUG_ANY, "Sample task starts (arg: %s) ...\n",
+ pb->pb_seq_val, 0, 0);
+ /* do real work */
+ rv = 0;
+
+ slapi_task_log_notice(task, "Sample task finished.");
+ slapi_task_log_status(task, "Sample task finished.");
+ LDAPDebug(LDAP_DEBUG_ANY, "Sample task finished.\n", 0, 0, 0);
+
+ task->task_progress = 1;
+ task->task_exitcode = rv;
+ task->task_state = SLAPI_TASK_FINISHED;
+ slapi_task_status_changed(task);
+
+ slapi_ch_free((void **)&pb->pb_seq_val);
+ slapi_pblock_destroy(pb);
+}
+
+/* extract a single value from the entry (as a string) -- if it's not in the
+ * entry, the default will be returned (which can be NULL).
+ * you do not need to free anything returned by this.
+ */
+static const char *fetch_attr(Slapi_Entry *e, const char *attrname,
+ const char *default_val)
+{
+ Slapi_Attr *attr;
+ Slapi_Value *val = NULL;
+
+ if (slapi_entry_attr_find(e, attrname, &attr) != 0)
+ return default_val;
+ slapi_attr_first_value(attr, &val);
+ return slapi_value_get_string(val);
+}
+
+/*
+ * Invoked when the task instance is added by the client (step 5 of the comment)
+ * Get the necessary attributes from the task entry, and spawns a thread to do
+ * the task.
+ */
+static int
+task_sampletask_add(Slapi_PBlock *pb, Slapi_Entry *e,
+ Slapi_Entry *eAfter, int *returncode, char *returntext,
+ void *arg)
+{
+ PRThread *thread = NULL;
+ const char *cn;
+ int rv = SLAPI_DSE_CALLBACK_OK;
+ Slapi_PBlock *mypb = NULL;
+ Slapi_Task *task = NULL;
+ const char *arg0;
+
+ *returncode = LDAP_SUCCESS;
+ if ((cn = fetch_attr(e, "cn", NULL)) == NULL) {
+ *returncode = LDAP_OBJECT_CLASS_VIOLATION;
+ rv = SLAPI_DSE_CALLBACK_ERROR;
+ goto out;
+ }
+
+ /* get arg(s) */
+ if ((arg0 = fetch_attr(e, "arg0", NULL)) == NULL) {
+ *returncode = LDAP_OBJECT_CLASS_VIOLATION;
+ rv = SLAPI_DSE_CALLBACK_ERROR;
+ goto out;
+ }
+
+ /* allocate new task now */
+ task = slapi_new_task(slapi_entry_get_ndn(e));
+ if (task == NULL) {
+ LDAPDebug(LDAP_DEBUG_ANY, "unable to allocate new task!\n", 0, 0, 0);
+ *returncode = LDAP_OPERATIONS_ERROR;
+ rv = SLAPI_DSE_CALLBACK_ERROR;
+ goto out;
+ }
+ task->task_state = SLAPI_TASK_SETUP;
+ task->task_work = 1;
+ task->task_progress = 0;
+
+ /* create a pblock to pass the necessary info to the task thread */
+ mypb = slapi_pblock_new();
+ if (mypb == NULL) {
+ *returncode = LDAP_OPERATIONS_ERROR;
+ rv = SLAPI_DSE_CALLBACK_ERROR;
+ goto out;
+ }
+ mypb->pb_seq_val = slapi_ch_strdup(arg0);
+ mypb->pb_task = task;
+ mypb->pb_task_flags = TASK_RUNNING_AS_TASK;
+
+ /* start the sample task as a separate thread */
+ thread = PR_CreateThread(PR_USER_THREAD, task_sampletask_thread,
+ (void *)mypb, PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD,
+ PR_UNJOINABLE_THREAD, SLAPD_DEFAULT_THREAD_STACKSIZE);
+ if (thread == NULL) {
+ LDAPDebug(LDAP_DEBUG_ANY,
+ "unable to create sample task thread!\n", 0, 0, 0);
+ *returncode = LDAP_OPERATIONS_ERROR;
+ rv = SLAPI_DSE_CALLBACK_ERROR;
+ slapi_ch_free((void **)&mypb->pb_seq_val);
+ slapi_pblock_destroy(mypb);
+ goto out;
+ }
+
+ /* thread successful -- don't free the pb, let the thread do that. */
+ return SLAPI_DSE_CALLBACK_OK;
+
+out:
+ if (task) {
+ slapi_destroy_task(task);
+ }
+ return rv;
+}