From 3f1eaec4df040ee21b2baaef3f9efd1c5a5ca35f Mon Sep 17 00:00:00 2001 From: Nalin Dahyabhai Date: Thu, 3 Jul 2008 11:02:12 -0400 Subject: - also track the DN of the originating entry - hook bind (insufficient_access) and compare (unwilling_to_perform) requests --- src/back-sch.c | 95 ++++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 86 insertions(+), 9 deletions(-) (limited to 'src/back-sch.c') diff --git a/src/back-sch.c b/src/back-sch.c index 97d9f20..abd6ba5 100644 --- a/src/back-sch.c +++ b/src/back-sch.c @@ -62,6 +62,7 @@ struct backend_set_data { bool_t check_access; }; struct backend_entry_data { + Slapi_DN *original_entry_dn; Slapi_Entry *e; }; @@ -283,11 +284,12 @@ backend_set_config_read_config(struct plugin_state *state, Slapi_Entry *e, /* Create and destroy entry-specific data. */ static struct backend_entry_data * -backend_entry_make_entry_data(Slapi_Entry *e) +backend_entry_make_entry_data(Slapi_DN *original_entry_dn, Slapi_Entry *e) { struct backend_entry_data *ret; ret = malloc(sizeof(*ret)); if (ret != NULL) { + ret->original_entry_dn = slapi_sdn_dup(original_entry_dn); ret->e = e; } else { slapi_entry_free(e); @@ -300,6 +302,7 @@ backend_entry_free_entry_data(void *p) struct backend_entry_data *data; data = p; slapi_entry_free(data->e); + slapi_sdn_free(&data->original_entry_dn); free(data); } @@ -312,9 +315,11 @@ backend_set_entry_one(Slapi_Entry *e, struct backend_set_data *data) const char *rdnstr; int len, i, j; Slapi_Entry *entry; + Slapi_DN *e_dn; Slapi_RDN *srdn; plugin_id = data->common.state->plugin_desc->spd_id; + e_dn = slapi_entry_get_sdn(e); ndn = slapi_entry_get_ndn(e); /* Generate the RDN for the entry. */ rdn = format_get_data(data->common.state, e, @@ -389,7 +394,7 @@ backend_set_entry_one(Slapi_Entry *e, struct backend_set_data *data) map_data_set_entry(data->common.state, data->common.group, data->common.set, ndn, NULL, keys, -1, slapi_entry_get_ndn(entry), - backend_entry_make_entry_data(entry), + backend_entry_make_entry_data(e_dn, entry), backend_entry_free_entry_data); } else { slapi_log_error(SLAPI_LOG_PLUGIN, plugin_id, @@ -899,18 +904,24 @@ backend_search_cb(Slapi_PBlock *pb) return cbdata.answer ? -1 : 0; } -struct backend_write_cbdata { +/* Locate the entry for a given DN. */ +struct backend_locate_cbdata { + char *target_dn; +}; + + +/* Check if the target DN is part of this group's tree. If it is, return an + * insufficient-access error. */ +struct backend_group_check_scope_cbdata { struct plugin_state *state; char *target; Slapi_DN *target_dn; bool_t ours; }; - -/* Check if the target DN is part of this group's tree. */ static bool_t -backend_write_group_cb(const char *group, void *cb_data) +backend_group_check_scope_cb(const char *group, void *cb_data) { - struct backend_write_cbdata *cbdata; + struct backend_group_check_scope_cbdata *cbdata; Slapi_DN *group_dn; cbdata = cb_data; @@ -924,13 +935,37 @@ backend_write_group_cb(const char *group, void *cb_data) static int backend_write_cb(Slapi_PBlock *pb) { - struct backend_write_cbdata cbdata; + struct backend_group_check_scope_cbdata cbdata; + + slapi_pblock_get(pb, SLAPI_PLUGIN_PRIVATE, &cbdata.state); + slapi_pblock_get(pb, SLAPI_TARGET_DN, &cbdata.target); + cbdata.target_dn = slapi_sdn_new_dn_byval(cbdata.target); + cbdata.ours = FALSE; + map_data_foreach_domain(cbdata.state, backend_group_check_scope_cb, + &cbdata); + slapi_sdn_free(&cbdata.target_dn); + if (cbdata.ours) { + slapi_send_ldap_result(pb, + LDAP_INSUFFICIENT_ACCESS, + cbdata.target, + NULL, + 0, + NULL); + return -1; + } + return 0; +} +static int +backend_bind_cb(Slapi_PBlock *pb) +{ + struct backend_group_check_scope_cbdata cbdata; slapi_pblock_get(pb, SLAPI_PLUGIN_PRIVATE, &cbdata.state); slapi_pblock_get(pb, SLAPI_TARGET_DN, &cbdata.target); cbdata.target_dn = slapi_sdn_new_dn_byval(cbdata.target); cbdata.ours = FALSE; - map_data_foreach_domain(cbdata.state, backend_write_group_cb, &cbdata); + map_data_foreach_domain(cbdata.state, backend_group_check_scope_cb, + &cbdata); slapi_sdn_free(&cbdata.target_dn); if (cbdata.ours) { slapi_send_ldap_result(pb, @@ -943,6 +978,30 @@ backend_write_cb(Slapi_PBlock *pb) } return 0; } +static int +backend_compare_cb(Slapi_PBlock *pb) +{ + struct backend_group_check_scope_cbdata cbdata; + + slapi_pblock_get(pb, SLAPI_PLUGIN_PRIVATE, &cbdata.state); + slapi_pblock_get(pb, SLAPI_TARGET_DN, &cbdata.target); + cbdata.target_dn = slapi_sdn_new_dn_byval(cbdata.target); + cbdata.ours = FALSE; + map_data_foreach_domain(cbdata.state, backend_group_check_scope_cb, + &cbdata); + slapi_sdn_free(&cbdata.target_dn); + if (cbdata.ours) { + slapi_send_ldap_result(pb, + LDAP_UNWILLING_TO_PERFORM, + cbdata.target, + NULL, + 0, + NULL); + return -1; + } + return 0; +} + /* Populate our data cache. */ void backend_startup(struct plugin_state *state) @@ -955,11 +1014,27 @@ backend_init_preop(Slapi_PBlock *pb, struct plugin_state *state) { 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) { + slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, + "error hooking up bind callback\n"); + } + /* Intercept compare requests and return the right data. */ + if (slapi_pblock_set(pb, SLAPI_PLUGIN_PRE_COMPARE_FN, + backend_compare_cb) != 0) { + slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, + "error hooking up bind callback\n"); + } + /* Intercept search requests and return the right data. */ if (slapi_pblock_set(pb, SLAPI_PLUGIN_PRE_SEARCH_FN, backend_search_cb) != 0) { slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, "error hooking up search callback\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) { slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, @@ -980,6 +1055,8 @@ backend_init_preop(Slapi_PBlock *pb, struct plugin_state *state) slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, "error hooking up delete callback\n"); } + /* We don't hook abandonment requests. */ + /* We don't hook unbind requests. */ } void -- cgit