diff options
author | Noriko Hosoi <nhosoi@redhat.com> | 2012-08-31 14:42:05 -0700 |
---|---|---|
committer | Nalin Dahyabhai <nalin@redhat.com> | 2012-10-16 16:18:34 -0400 |
commit | c5bfff6c6e6ae5e255b2432be1ed8790a6c07e82 (patch) | |
tree | 1595673b93e151bdb2782717a62e2dcdf790679d | |
parent | 375c82e0cfc3d7494ddf63610353da30a77b4491 (diff) | |
download | slapi-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.c | 80 | ||||
-rw-r--r-- | src/back-shr.c | 47 | ||||
-rw-r--r-- | src/backend.h | 1 | ||||
-rw-r--r-- | src/plug-nis.c | 34 | ||||
-rw-r--r-- | src/plug-sch.c | 129 |
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"); |