summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNoriko Hosoi <nhosoi@redhat.com>2012-08-31 14:42:05 -0700
committerNalin Dahyabhai <nalin@redhat.com>2012-10-16 16:18:34 -0400
commitc5bfff6c6e6ae5e255b2432be1ed8790a6c07e82 (patch)
tree1595673b93e151bdb2782717a62e2dcdf790679d
parent375c82e0cfc3d7494ddf63610353da30a77b4491 (diff)
downloadslapi-nis-c5bfff6c6e6ae5e255b2432be1ed8790a6c07e82.tar.gz
slapi-nis-c5bfff6c6e6ae5e255b2432be1ed8790a6c07e82.tar.xz
slapi-nis-c5bfff6c6e6ae5e255b2432be1ed8790a6c07e82.zip
make NIS Plugin and Schema Compatibility Plugin betxn aware
When NIS Plugin and Schema Compatibility Plugin config entries include nsslapd-pluginbetxn: on (the value could be yes, true or 1, too), the plugins' update callbacks (add, delete, modify, and modrdn) are called at the betxn pre/postop timing. By default, the value of nsslapd-pluginbetxn is off. (See also https://fedorahosted.org/389/ticket/351)
-rw-r--r--src/back-sch.c80
-rw-r--r--src/back-shr.c47
-rw-r--r--src/backend.h1
-rw-r--r--src/plug-nis.c34
-rw-r--r--src/plug-sch.c129
5 files changed, 226 insertions, 65 deletions
diff --git a/src/back-sch.c b/src/back-sch.c
index aecea67..e889458 100644
--- a/src/back-sch.c
+++ b/src/back-sch.c
@@ -1441,52 +1441,104 @@ backend_startup(Slapi_PBlock *pb, struct plugin_state *state)
int
backend_init_preop(Slapi_PBlock *pb, struct plugin_state *state)
{
+ int bindfn = SLAPI_PLUGIN_PRE_BIND_FN;
+ int cmpfn = SLAPI_PLUGIN_PRE_COMPARE_FN;
+ int srchfn = SLAPI_PLUGIN_PRE_SEARCH_FN;
+ int addfn = SLAPI_PLUGIN_PRE_ADD_FN;
+ int modfn = SLAPI_PLUGIN_PRE_MODIFY_FN;
+ int mdnfn = SLAPI_PLUGIN_PRE_MODRDN_FN;
+ int delfn = SLAPI_PLUGIN_PRE_DELETE_FN;
+ Slapi_Entry *plugin_entry = NULL;
+ char *plugin_type = NULL;
+ int is_betxn = 0;
+
+ if ((slapi_pblock_get(pb, SLAPI_PLUGIN_CONFIG_ENTRY, &plugin_entry) == 0) &&
+ plugin_entry &&
+ (plugin_type = slapi_entry_attr_get_charptr(plugin_entry, "nsslapd-plugintype")) &&
+ plugin_type && strstr(plugin_type, "betxn")) {
+ is_betxn = 1;
+ }
+ slapi_ch_free_string(&plugin_type);
+
slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id,
"hooking up preoperation callbacks\n");
/* Intercept bind requests and return a referral or failure for entries
* that we're managing. */
- if (slapi_pblock_set(pb, SLAPI_PLUGIN_PRE_BIND_FN,
- backend_bind_cb) != 0) {
+ if (slapi_pblock_set(pb, bindfn, backend_bind_cb) != 0) {
slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id,
"error hooking up bind callback\n");
return -1;
}
/* Intercept compare requests and return the right data. */
- if (slapi_pblock_set(pb, SLAPI_PLUGIN_PRE_COMPARE_FN,
- backend_compare_cb) != 0) {
+ if (slapi_pblock_set(pb, cmpfn, backend_compare_cb) != 0) {
slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id,
"error hooking up compare callback\n");
return -1;
}
/* Intercept search requests and return the right data. */
- if (slapi_pblock_set(pb, SLAPI_PLUGIN_PRE_SEARCH_FN,
- backend_search_cb) != 0) {
+ if (slapi_pblock_set(pb, srchfn, backend_search_cb) != 0) {
slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id,
"error hooking up search callback\n");
return -1;
}
+ if (!is_betxn) {
+ /* if is_betxn, these callbacks are registered for betxnpreop */
+ /* Intercept write requests and return an insufficient-access error for
+ * attempts to write to anything we're managing. */
+ if (slapi_pblock_set(pb, addfn, backend_write_cb) != 0) {
+ slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id,
+ "error hooking up add callback\n");
+ return -1;
+ }
+ if (slapi_pblock_set(pb, modfn, backend_write_cb) != 0) {
+ slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id,
+ "error hooking up modify callback\n");
+ return -1;
+ }
+ if (slapi_pblock_set(pb, mdnfn, backend_write_cb) != 0) {
+ slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id,
+ "error hooking up modrdn callback\n");
+ return -1;
+ }
+ if (slapi_pblock_set(pb, delfn, backend_write_cb) != 0) {
+ slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id,
+ "error hooking up delete callback\n");
+ return -1;
+ }
+ }
+ /* We don't hook abandonment requests. */
+ /* We don't hook unbind requests. */
+ return 0;
+}
+
+int
+backend_init_betxnpreop(Slapi_PBlock *pb, struct plugin_state *state)
+{
+ int addfn = SLAPI_PLUGIN_BE_TXN_PRE_ADD_FN;
+ int modfn = SLAPI_PLUGIN_BE_TXN_PRE_MODIFY_FN;
+ int mdnfn = SLAPI_PLUGIN_BE_TXN_PRE_MODRDN_FN;
+ int delfn = SLAPI_PLUGIN_BE_TXN_PRE_DELETE_FN;
+
+ slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id,
+ "hooking up betxn preoperation callbacks\n");
/* Intercept write requests and return an insufficient-access error for
* attempts to write to anything we're managing. */
- if (slapi_pblock_set(pb, SLAPI_PLUGIN_PRE_ADD_FN,
- backend_write_cb) != 0) {
+ if (slapi_pblock_set(pb, addfn, backend_write_cb) != 0) {
slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id,
"error hooking up add callback\n");
return -1;
}
- if (slapi_pblock_set(pb, SLAPI_PLUGIN_PRE_MODIFY_FN,
- backend_write_cb) != 0) {
+ if (slapi_pblock_set(pb, modfn, backend_write_cb) != 0) {
slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id,
"error hooking up modify callback\n");
return -1;
}
- if (slapi_pblock_set(pb, SLAPI_PLUGIN_PRE_MODRDN_FN,
- backend_write_cb) != 0) {
+ if (slapi_pblock_set(pb, mdnfn, backend_write_cb) != 0) {
slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id,
"error hooking up modrdn callback\n");
return -1;
}
- if (slapi_pblock_set(pb, SLAPI_PLUGIN_PRE_DELETE_FN,
- backend_write_cb) != 0) {
+ if (slapi_pblock_set(pb, delfn, backend_write_cb) != 0) {
slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id,
"error hooking up delete callback\n");
return -1;
diff --git a/src/back-shr.c b/src/back-shr.c
index a2c31c9..99955b6 100644
--- a/src/back-shr.c
+++ b/src/back-shr.c
@@ -2245,26 +2245,40 @@ backend_shr_internal_delete_cb(Slapi_PBlock *pb)
int
backend_shr_postop_init(Slapi_PBlock *pb, struct plugin_state *state)
{
- if (slapi_pblock_set(pb, SLAPI_PLUGIN_POST_ADD_FN,
- backend_shr_add_cb) != 0) {
+ int addfn = SLAPI_PLUGIN_POST_ADD_FN;
+ int modfn = SLAPI_PLUGIN_POST_MODIFY_FN;
+ int mdnfn = SLAPI_PLUGIN_POST_MODRDN_FN;
+ int delfn = SLAPI_PLUGIN_POST_DELETE_FN;
+ Slapi_Entry *plugin_entry = NULL;
+ char *plugin_type = NULL;
+
+ if ((slapi_pblock_get(pb, SLAPI_PLUGIN_CONFIG_ENTRY, &plugin_entry) == 0) &&
+ plugin_entry &&
+ (plugin_type = slapi_entry_attr_get_charptr(plugin_entry, "nsslapd-plugintype")) &&
+ plugin_type && strstr(plugin_type, "betxn")) {
+ addfn = SLAPI_PLUGIN_BE_TXN_POST_ADD_FN;
+ modfn = SLAPI_PLUGIN_BE_TXN_POST_MODIFY_FN;
+ mdnfn = SLAPI_PLUGIN_BE_TXN_POST_MODRDN_FN;
+ delfn = SLAPI_PLUGIN_BE_TXN_POST_DELETE_FN;
+ }
+ slapi_ch_free_string(&plugin_type);
+
+ if (slapi_pblock_set(pb, addfn, backend_shr_add_cb) != 0) {
slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id,
"error hooking up add callback\n");
return -1;
}
- if (slapi_pblock_set(pb, SLAPI_PLUGIN_POST_MODIFY_FN,
- backend_shr_modify_cb) != 0) {
+ if (slapi_pblock_set(pb, modfn, backend_shr_modify_cb) != 0) {
slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id,
"error hooking up modify callback\n");
return -1;
}
- if (slapi_pblock_set(pb, SLAPI_PLUGIN_POST_MODRDN_FN,
- backend_shr_modrdn_cb) != 0) {
+ if (slapi_pblock_set(pb, mdnfn, backend_shr_modrdn_cb) != 0) {
slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id,
"error hooking up modrdn callback\n");
return -1;
}
- if (slapi_pblock_set(pb, SLAPI_PLUGIN_POST_DELETE_FN,
- backend_shr_delete_cb) != 0) {
+ if (slapi_pblock_set(pb, delfn, backend_shr_delete_cb) != 0) {
slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id,
"error hooking up delete callback\n");
return -1;
@@ -2275,26 +2289,27 @@ backend_shr_postop_init(Slapi_PBlock *pb, struct plugin_state *state)
int
backend_shr_internal_postop_init(Slapi_PBlock *pb, struct plugin_state *state)
{
- if (slapi_pblock_set(pb, SLAPI_PLUGIN_INTERNAL_POST_ADD_FN,
- backend_shr_internal_add_cb) != 0) {
+ int addfn = SLAPI_PLUGIN_INTERNAL_POST_ADD_FN;
+ int modfn = SLAPI_PLUGIN_INTERNAL_POST_MODIFY_FN;
+ int mdnfn = SLAPI_PLUGIN_INTERNAL_POST_MODRDN_FN;
+ int delfn = SLAPI_PLUGIN_INTERNAL_POST_DELETE_FN;
+
+ if (slapi_pblock_set(pb, addfn, backend_shr_internal_add_cb) != 0) {
slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id,
"error hooking up internal add callback\n");
return -1;
}
- if (slapi_pblock_set(pb, SLAPI_PLUGIN_INTERNAL_POST_MODIFY_FN,
- backend_shr_internal_modify_cb) != 0) {
+ if (slapi_pblock_set(pb, modfn, backend_shr_internal_modify_cb) != 0) {
slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id,
"error hooking up internal modify callback\n");
return -1;
}
- if (slapi_pblock_set(pb, SLAPI_PLUGIN_INTERNAL_POST_MODRDN_FN,
- backend_shr_internal_modrdn_cb) != 0) {
+ if (slapi_pblock_set(pb, mdnfn, backend_shr_internal_modrdn_cb) != 0) {
slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id,
"error hooking up internal modrdn callback\n");
return -1;
}
- if (slapi_pblock_set(pb, SLAPI_PLUGIN_INTERNAL_POST_DELETE_FN,
- backend_shr_internal_delete_cb) != 0) {
+ if (slapi_pblock_set(pb, delfn, backend_shr_internal_delete_cb) != 0) {
slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id,
"error hooking up internal delete callback\n");
return -1;
diff --git a/src/backend.h b/src/backend.h
index 7f52915..6dff74f 100644
--- a/src/backend.h
+++ b/src/backend.h
@@ -52,6 +52,7 @@ struct backend_shr_set_data {
/* Startup/initialization functions called through the map. */
void backend_startup(struct slapi_pblock *pb, struct plugin_state *state);
int backend_init_preop(struct slapi_pblock *pb, struct plugin_state *state);
+int backend_init_betxnpreop(struct slapi_pblock *pb, struct plugin_state *state);
int backend_init_postop(struct slapi_pblock *pb, struct plugin_state *state);
int backend_init_internal_postop(struct slapi_pblock *pb,
struct plugin_state *state);
diff --git a/src/plug-nis.c b/src/plug-nis.c
index 4c7ba98..201ba4e 100644
--- a/src/plug-nis.c
+++ b/src/plug-nis.c
@@ -482,6 +482,18 @@ int
nis_plugin_init(Slapi_PBlock *pb)
{
struct plugin_state *state = NULL;
+ Slapi_Entry *plugin_entry = NULL;
+ int is_betxn = 0;
+ char *plugin_type = "postoperation";
+
+ /* get args */
+ if ((slapi_pblock_get(pb, SLAPI_PLUGIN_CONFIG_ENTRY, &plugin_entry) == 0) &&
+ plugin_entry) {
+ is_betxn = slapi_entry_attr_get_bool(plugin_entry,
+ "nsslapd-pluginbetxn");
+ plugin_type = "betxnpostoperation";
+ }
+
/* Allocate the module-global data and set up listening sockets. */
if (plugin_state_init(pb, &state) == -1) {
slapi_log_error(SLAPI_LOG_PLUGIN, plugin_description.spd_id,
@@ -498,7 +510,7 @@ nis_plugin_init(Slapi_PBlock *pb)
slapi_pblock_set(pb, SLAPI_PLUGIN_PRIVATE, state);
/* Register the sub-plugins. */
global_plugin_state = state;
- if (slapi_register_plugin("postoperation", TRUE,
+ if (slapi_register_plugin(plugin_type, TRUE,
"nis_plugin_init_postop",
nis_plugin_init_postop,
PLUGIN_POSTOP_ID, NULL,
@@ -507,14 +519,18 @@ nis_plugin_init(Slapi_PBlock *pb)
"error registering postoperation plugin\n");
return -1;
}
- if (slapi_register_plugin("internalpostoperation", TRUE,
- "nis_plugin_init_internal_postop",
- nis_plugin_init_internal_postop,
- PLUGIN_INTERNAL_POSTOP_ID, NULL,
- state->plugin_identity) != 0) {
- slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id,
- "error registering internal postoperation plugin\n");
- return -1;
+ if (!is_betxn) {
+ /* if betxn is on, the plugin is called inside of backend transaction,
+ * which does not distinguish the internal operation. */
+ if (slapi_register_plugin("internalpostoperation", TRUE,
+ "nis_plugin_init_internal_postop",
+ nis_plugin_init_internal_postop,
+ PLUGIN_INTERNAL_POSTOP_ID, NULL,
+ state->plugin_identity) != 0) {
+ slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id,
+ "error registering internal postoperation plugin\n");
+ return -1;
+ }
}
slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id,
"registered plugin hooks\n");
diff --git a/src/plug-sch.c b/src/plug-sch.c
index 44b0918..cb4a63e 100644
--- a/src/plug-sch.c
+++ b/src/plug-sch.c
@@ -123,6 +123,7 @@ plugin_shutdown(Slapi_PBlock *pb)
return 0;
}
+/* preoperation: all callbacks are called at preop */
static int
schema_compat_plugin_init_preop(Slapi_PBlock *pb)
{
@@ -137,6 +138,39 @@ schema_compat_plugin_init_preop(Slapi_PBlock *pb)
}
return 0;
}
+
+/* betxnpreoperation: bind, compare and search callbacks are called at preop */
+static int
+schema_compat_plugin_init_betxnpreop_preop(Slapi_PBlock *pb)
+{
+ slapi_pblock_set(pb, SLAPI_PLUGIN_VERSION, SLAPI_PLUGIN_VERSION_03);
+ slapi_pblock_set(pb, SLAPI_PLUGIN_DESCRIPTION, &plugin_description);
+ slapi_pblock_set(pb, SLAPI_PLUGIN_PRIVATE, global_plugin_state);
+ if (backend_init_preop(pb, global_plugin_state) == -1) {
+ slapi_log_error(SLAPI_LOG_PLUGIN,
+ global_plugin_state->plugin_desc->spd_id,
+ "error registering preoperation hooks\n");
+ return -1;
+ }
+ return 0;
+}
+
+/* betxnpreoperation: add, delete, modify and modrdn callbacks are called at betxnpreop */
+static int
+schema_compat_plugin_init_betxnpreop(Slapi_PBlock *pb)
+{
+ slapi_pblock_set(pb, SLAPI_PLUGIN_VERSION, SLAPI_PLUGIN_VERSION_03);
+ slapi_pblock_set(pb, SLAPI_PLUGIN_DESCRIPTION, &plugin_description);
+ slapi_pblock_set(pb, SLAPI_PLUGIN_PRIVATE, global_plugin_state);
+ if (backend_init_betxnpreop(pb, global_plugin_state) == -1) {
+ slapi_log_error(SLAPI_LOG_PLUGIN,
+ global_plugin_state->plugin_desc->spd_id,
+ "error registering preoperation hooks\n");
+ return -1;
+ }
+ return 0;
+}
+
static int
schema_compat_plugin_init_postop(Slapi_PBlock *pb)
{
@@ -169,6 +203,16 @@ int
schema_compat_plugin_init(Slapi_PBlock *pb)
{
struct plugin_state *state = NULL;
+ Slapi_Entry *plugin_entry = NULL;
+ int is_betxn = 0;
+
+ /* get args */
+ if ((slapi_pblock_get(pb, SLAPI_PLUGIN_CONFIG_ENTRY, &plugin_entry) == 0) &&
+ plugin_entry) {
+ is_betxn = slapi_entry_attr_get_bool(plugin_entry,
+ "nsslapd-pluginbetxn");
+ }
+
/* Allocate a memory pool. */
if (plugin_state_init(pb, &state) == -1) {
slapi_log_error(SLAPI_LOG_PLUGIN, plugin_description.spd_id,
@@ -185,32 +229,65 @@ schema_compat_plugin_init(Slapi_PBlock *pb)
slapi_pblock_set(pb, SLAPI_PLUGIN_PRIVATE, state);
/* Register the sub-plugins. */
global_plugin_state = state;
- if (slapi_register_plugin("preoperation", TRUE,
- "schema_compat_plugin_init_preop",
- schema_compat_plugin_init_preop,
- PLUGIN_PREOP_ID, NULL,
- state->plugin_identity) != 0) {
- slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id,
- "error registering preoperation plugin\n");
- return -1;
- }
- if (slapi_register_plugin("postoperation", TRUE,
- "schema_compat_plugin_init_postop",
- schema_compat_plugin_init_postop,
- PLUGIN_POSTOP_ID, NULL,
- state->plugin_identity) != 0) {
- slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id,
- "error registering postoperation plugin\n");
- return -1;
- }
- if (slapi_register_plugin("internalpostoperation", TRUE,
- "schema_compat_plugin_init_internal_postop",
- schema_compat_plugin_init_internal_postop,
- PLUGIN_INTERNAL_POSTOP_ID, NULL,
- state->plugin_identity) != 0) {
- slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id,
- "error registering internal postoperation plugin\n");
- return -1;
+ if (is_betxn) {
+ /* bind, compare and search callbacks are called at preop */
+ if (slapi_register_plugin("preoperation", TRUE,
+ "schema_compat_plugin_init_betxnpreop_preop",
+ schema_compat_plugin_init_betxnpreop_preop,
+ PLUGIN_PREOP_ID, NULL,
+ state->plugin_identity) != 0) {
+ slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id,
+ "error registering betxn preoperation plugin\n");
+ return -1;
+ }
+ /* add, delete, modify and modrdn callbacks are called at betxnpreop */
+ if (slapi_register_plugin("betxnpreoperation", TRUE,
+ "schema_compat_plugin_init_betxnpreop",
+ schema_compat_plugin_init_betxnpreop,
+ PLUGIN_PREOP_ID, NULL,
+ state->plugin_identity) != 0) {
+ slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id,
+ "error registering betxn preoperation plugin\n");
+ return -1;
+ }
+ if (slapi_register_plugin("betxnpostoperation", TRUE,
+ "schema_compat_plugin_init_postop",
+ schema_compat_plugin_init_postop,
+ PLUGIN_POSTOP_ID, NULL,
+ state->plugin_identity) != 0) {
+ slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id,
+ "error registering postoperation plugin\n");
+ return -1;
+ }
+ } else {
+ /* preoperation: all callbacks are called at preop */
+ if (slapi_register_plugin("preoperation", TRUE,
+ "schema_compat_plugin_init_preop",
+ schema_compat_plugin_init_preop,
+ PLUGIN_PREOP_ID, NULL,
+ state->plugin_identity) != 0) {
+ slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id,
+ "error registering preoperation plugin\n");
+ return -1;
+ }
+ if (slapi_register_plugin("postoperation", TRUE,
+ "schema_compat_plugin_init_postop",
+ schema_compat_plugin_init_postop,
+ PLUGIN_POSTOP_ID, NULL,
+ state->plugin_identity) != 0) {
+ slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id,
+ "error registering postoperation plugin\n");
+ return -1;
+ }
+ if (slapi_register_plugin("internalpostoperation", TRUE,
+ "schema_compat_plugin_init_internal_postop",
+ schema_compat_plugin_init_internal_postop,
+ PLUGIN_INTERNAL_POSTOP_ID, NULL,
+ state->plugin_identity) != 0) {
+ slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id,
+ "error registering internal postoperation plugin\n");
+ return -1;
+ }
}
slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id,
"registered plugin hooks\n");