summaryrefslogtreecommitdiffstats
path: root/src/back-sch.c
diff options
context:
space:
mode:
authorNalin Dahyabhai <nalin.dahyabhai@pobox.com>2008-07-03 11:02:12 -0400
committerNalin Dahyabhai <nalin.dahyabhai@pobox.com>2008-07-03 11:02:12 -0400
commit3f1eaec4df040ee21b2baaef3f9efd1c5a5ca35f (patch)
tree6cb35b1d3bec46844e778752ef5201cb55a17f20 /src/back-sch.c
parent53bea9986215588b1b8efd5288dbae911aee5a73 (diff)
downloadslapi-nis-3f1eaec4df040ee21b2baaef3f9efd1c5a5ca35f.tar.gz
slapi-nis-3f1eaec4df040ee21b2baaef3f9efd1c5a5ca35f.tar.xz
slapi-nis-3f1eaec4df040ee21b2baaef3f9efd1c5a5ca35f.zip
- also track the DN of the originating entry
- hook bind (insufficient_access) and compare (unwilling_to_perform) requests
Diffstat (limited to 'src/back-sch.c')
-rw-r--r--src/back-sch.c95
1 files changed, 86 insertions, 9 deletions
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