diff options
| author | Nalin Dahyabhai <nalin.dahyabhai@pobox.com> | 2008-07-03 13:33:03 -0400 |
|---|---|---|
| committer | Nalin Dahyabhai <nalin.dahyabhai@pobox.com> | 2008-07-03 13:33:03 -0400 |
| commit | afeacf387f97ca097a856612d94f01e695fb1a9c (patch) | |
| tree | 8a4707ca031a170d1f4fca63289060534aa966b7 /src | |
| parent | 2f1b5994a48038e267de36cae3ae2484a7b9cd58 (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.c | 178 |
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. */ |
