summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorNalin Dahyabhai <nalin.dahyabhai@pobox.com>2008-07-03 13:33:03 -0400
committerNalin Dahyabhai <nalin.dahyabhai@pobox.com>2008-07-03 13:33:03 -0400
commitafeacf387f97ca097a856612d94f01e695fb1a9c (patch)
tree8a4707ca031a170d1f4fca63289060534aa966b7 /src
parent2f1b5994a48038e267de36cae3ae2484a7b9cd58 (diff)
- factor out checking if an entry is one of ours
- add a function to retrieve the entry data for a given RDN - during bind requests, return a referral to the right entry if it's not one we just made up, else fail the bind - fail to compare anything we're supplying.... for now
Diffstat (limited to 'src')
-rw-r--r--src/back-sch.c178
1 files changed, 128 insertions, 50 deletions
diff --git a/src/back-sch.c b/src/back-sch.c
index dd0ccb8..29216c8 100644
--- a/src/back-sch.c
+++ b/src/back-sch.c
@@ -893,7 +893,9 @@ backend_search_cb(Slapi_PBlock *pb)
cbdata.matched = "";
cbdata.text = "";
cbdata.n_entries = 0;
+ map_rdlock();
map_data_foreach_domain(cbdata.state, backend_search_group_cb, &cbdata);
+ map_unlock();
slapi_sdn_free(&cbdata.target_dn);
if (cbdata.answer) {
slapi_send_ldap_result(cbdata.pb, cbdata.result,
@@ -906,15 +908,67 @@ backend_search_cb(Slapi_PBlock *pb)
/* Locate the entry for a given DN. */
struct backend_locate_cbdata {
- char *target_dn;
+ struct plugin_state *state;
+ char *target;
+ Slapi_DN *target_dn;
+
+ struct backend_entry_data *entry_data;
};
+/* Check if the target DN is an entry in this container's set of entries. If
+ * it is, pull the entry's data out and save it. */
+static bool_t
+backend_locate_cb(const char *group, const char *set, bool_t flag,
+ void *backend_set_data, void *cb_data)
+{
+ struct backend_locate_cbdata *cbdata;
+ struct backend_set_data *set_data;
+ struct backend_entry_data *entry_data;
+ Slapi_RDN *rdn;
+ const char *rdnstr, *ndn, *original_dn;
+ unsigned int ndnlen;
+
+ cbdata = cb_data;
+ set_data = backend_set_data;
+ /* Check if the target DN looks like it would be part of this set. */
+ if (slapi_sdn_scope_test(cbdata->target_dn, set_data->container_sdn,
+ LDAP_SCOPE_ONE)) {
+ /* Pull out the RDN and check for an entry which is using the
+ * RDN as a key. */
+ rdn = slapi_rdn_new_sdn(cbdata->target_dn);
+ if (rdn != NULL) {
+ rdnstr = slapi_rdn_get_rdn(rdn);
+ if (map_match(cbdata->state, group, set, &flag,
+ strlen(rdnstr), rdnstr,
+ &ndnlen, &ndn,
+ &original_dn, (void **) &entry_data)) {
+ if (entry_data != NULL) {
+ cbdata->entry_data = entry_data;
+ }
+ }
+ slapi_rdn_free(&rdn);
+ }
+ }
+ return TRUE;
+}
+static void
+backend_locate(Slapi_PBlock *pb, struct backend_entry_data **data)
+{
+ struct backend_locate_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.entry_data = NULL;
+ map_data_foreach_map(cbdata.state, NULL, backend_locate_cb, &cbdata);
+ *data = cbdata.entry_data;
+ slapi_sdn_free(&cbdata.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;
+ const char *target;
Slapi_DN *target_dn;
bool_t ours;
};
@@ -932,74 +986,98 @@ backend_group_check_scope_cb(const char *group, void *cb_data)
slapi_sdn_free(&group_dn);
return TRUE;
}
-static int
-backend_write_cb(Slapi_PBlock *pb)
+static bool_t
+backend_check_scope(struct plugin_state *state, const char *target)
{
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.state = state;
+ cbdata.target = target;
cbdata.target_dn = slapi_sdn_new_dn_byval(cbdata.target);
cbdata.ours = FALSE;
+ map_rdlock();
map_data_foreach_domain(cbdata.state, backend_group_check_scope_cb,
&cbdata);
+ map_unlock();
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 cbdata.ours;
+}
+static bool_t
+backend_check_scope_pb(Slapi_PBlock *pb)
+{
+ struct plugin_state *state;
+ char *target;
+
+ slapi_pblock_get(pb, SLAPI_PLUGIN_PRIVATE, &state);
+ slapi_pblock_get(pb, SLAPI_TARGET_DN, &target);
+ return backend_check_scope(state, target);
+}
+static int
+backend_write_cb(Slapi_PBlock *pb)
+{
+ int ret;
+ map_rdlock();
+ if (backend_check_scope_pb(pb)) {
+ slapi_send_ldap_result(pb, LDAP_INSUFFICIENT_ACCESS,
+ NULL, NULL, 0, NULL);
+ ret = -1;
+ } else {
+ ret = 0;
}
- return 0;
+ map_unlock();
+ return ret;
}
static int
backend_bind_cb(Slapi_PBlock *pb)
{
- struct backend_group_check_scope_cbdata cbdata;
+ struct backend_entry_data *data;
+ int ret;
+ struct berval ref;
+ struct berval *urls[] = {&ref, NULL};
+ const char *ndn;
- 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;
+ map_rdlock();
+ backend_locate(pb, &data);
+ if (data != NULL) {
+ ndn = slapi_sdn_get_ndn(data->original_entry_dn);
+ ref.bv_len = strlen("ldap:///") + strlen(ndn);
+ ref.bv_val = malloc(ref.bv_len + 1);
+ if (ref.bv_val != NULL) {
+ sprintf(ref.bv_val, "ldap:///%s", ndn);
+ slapi_send_ldap_result(pb, LDAP_REFERRAL,
+ NULL, NULL, 0, urls);
+ free(ref.bv_val);
+ } else {
+ slapi_send_ldap_result(pb, LDAP_BUSY,
+ NULL, NULL, 0, NULL);
+ }
+ ret = -1;
+ } else {
+ if (backend_check_scope_pb(pb)) {
+ slapi_send_ldap_result(pb, LDAP_INVALID_CREDENTIALS,
+ NULL, NULL, 0, NULL);
+ ret = -1;
+ } else {
+ ret = 0;
+ }
}
- return 0;
+ map_unlock();
+ return ret;
}
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;
+ int ret;
+ map_rdlock();
+ if (backend_check_scope_pb(pb)) {
+ slapi_send_ldap_result(pb, LDAP_UNWILLING_TO_PERFORM,
+ NULL, NULL, 0, NULL);
+ ret = -1;
+ } else {
+ ret = 0;
}
- return 0;
+ map_unlock();
+ return ret;
}
/* Populate our data cache. */