summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexander Sulfrian <alex@spline.inf.fu-berlin.de>2016-01-21 04:42:17 +0100
committerAlexander Sulfrian <alex@spline.inf.fu-berlin.de>2016-01-21 04:42:17 +0100
commit88efff5ae386040768925943ae8d0824e6e15f6e (patch)
treea2b76d6c0a29d364a23f4aa1b736d09ae0ef2e02
parent8e0b96e46884c5048082f5ffff5cec37443f8003 (diff)
downloadldap-plugin-88efff5ae386040768925943ae8d0824e6e15f6e.tar.gz
ldap-plugin-88efff5ae386040768925943ae8d0824e6e15f6e.tar.bz2
ldap-plugin-88efff5ae386040768925943ae8d0824e6e15f6e.zip
Rewrite the base dn if needed in pre_search
If a service wants to get the user information by searching for the user DN explicitly (maybe with a BASE search scope), we need to drop the virtual prefix for the service (the virtual entry might not even exists or does not have the requested user infromation). The pre_search plugin method is executed before all searches and modifies the TARGET_DN if required.
-rw-r--r--service_passwords.c78
1 files changed, 78 insertions, 0 deletions
diff --git a/service_passwords.c b/service_passwords.c
index a8e2700..56c6e58 100644
--- a/service_passwords.c
+++ b/service_passwords.c
@@ -617,6 +617,83 @@ fail1:
return rc;
}
+/** \c PRE_SEARCH plugin to rewrite the search base if it is set to the virtual
+ * service entry.
+ *
+ * Most applications want to get the user information of a user. Some might get
+ * this information by searching with the user DN as base DN. This does not work
+ * for the virtual service DNs, because this entries might not exists.
+ *
+ * So for all searches that are executed in an authenticated connection
+ * (authenticated as service account or user) the virtual prefix is dropped, if
+ * the base DN is the virtual user entry. The \c PRE_ENTRY hook rewrites the
+ * found user entry to the requested virtual user entry. This does nocht work,
+ * if the client explicitly searches with a search filter for \c cn, but it is
+ * sufficient.
+ *
+ * @param[in,out] pb Parameter block of the operation.
+ * @return The return value do not have influence on the search operation by
+ * itself. It only stops further plugin processing (other plguins), if
+ * it is not equal 0.
+ */
+static int pre_search(Slapi_PBlock *pb)
+{
+ char *bind_dn;
+ char *base;
+ int is_replication;
+ int is_internal;
+
+ char *parent_dn = NULL;
+
+ int rc = 0;
+ char fn[] = "pre_search in service_passwords plug-in";
+
+ rc |= slapi_pblock_get(pb, SLAPI_CONN_DN, &bind_dn);
+ rc |= slapi_pblock_get(pb, SLAPI_TARGET_DN, &base);
+ rc |= slapi_pblock_get(pb, SLAPI_IS_REPLICATED_OPERATION, &is_replication);
+ rc |= slapi_pblock_get(pb, SLAPI_IS_INTERNAL_OPERATION, &is_internal);
+
+ if (rc != 0) {
+ slapi_log_error(
+ SLAPI_LOG_PLUGIN, fn,
+ "Could not get parameters (error %d).\n",
+ rc);
+
+ slapi_send_ldap_result(
+ pb, LDAP_OPERATIONS_ERROR, NULL, NULL, 0, NULL);
+ return LDAP_OPERATIONS_ERROR;
+ }
+
+ if (is_replication || is_internal) {
+ return 0;
+ }
+
+ if (bind_dn == NULL) {
+ /* only handle authenticated searches */
+ return 0;
+ }
+
+ if (is_service(bind_dn, NULL) != 0) {
+ parent_dn = slapi_dn_parent(bind_dn);
+ rc |= is_user(parent_dn);
+ slapi_ch_free_string(&parent_dn);
+
+ if (rc != 0) {
+ return 0;
+ }
+ }
+
+ parent_dn = slapi_dn_parent(base);
+
+ if (is_user(parent_dn) == 0) {
+ rc |= slapi_pblock_set(pb, SLAPI_TARGET_DN, parent_dn);
+ }
+
+ slapi_ch_free_string(&parent_dn);
+
+ return rc;
+}
+
Slapi_PluginDesc bindpdesc = {
.spd_id = "service_passwords",
.spd_vendor = "spline",
@@ -633,6 +710,7 @@ int service_passwords_init(Slapi_PBlock *pb)
rc |= slapi_pblock_set(pb, SLAPI_PLUGIN_DESCRIPTION, (void *) &bindpdesc);
rc |= slapi_pblock_set(pb, SLAPI_PLUGIN_PRE_BIND_FN, (void *) pre_bind);
rc |= slapi_pblock_set(pb, SLAPI_PLUGIN_PRE_ENTRY_FN, (void *) pre_entry);
+ rc |= slapi_pblock_set(pb, SLAPI_PLUGIN_PRE_SEARCH_FN, (void *) pre_search);
rc |= slapi_pblock_get(pb, SLAPI_PLUGIN_IDENTITY, &plugin_id);
return rc;
}