summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--service_passwords.c40
1 files changed, 39 insertions, 1 deletions
diff --git a/service_passwords.c b/service_passwords.c
index d150e45..983ee08 100644
--- a/service_passwords.c
+++ b/service_passwords.c
@@ -385,6 +385,36 @@ static Slapi_Entry *prepend_service_prefix(Slapi_Entry *entry, char *service)
return new_entry;
}
+/** The the name of the service specified by the virtual entry for a user.
+ *
+ * This function splits the DN in single RDN values, get the first and returns
+ * the value if the type is "cn" (aka. commonName).
+ *
+ * @param[in] dn The dn of the virtual entry.
+ * @return Pointer to the service name or NULL if the type of the first RDN is
+ * not "cn". If a pointer is returned the caller is responsible for
+ * freeing it with \c slapi_ch_free_string.
+ */
+static char *get_virtual_service(const char *dn)
+{
+ Slapi_RDN *rdn = NULL;
+ char *service = NULL;
+ char *type = NULL;
+ char *value = NULL;
+
+ rdn = slapi_rdn_new();
+ slapi_rdn_set_dn(rdn, dn);
+ slapi_rdn_get_first(rdn, &type, &value);
+
+ if (strcmp(type, "cn") == 0) {
+ service = slapi_ch_strdup(value);
+ }
+
+ slapi_rdn_free(&rdn);
+
+ return service;
+}
+
/** \c PRE_BIND plugin to allow password fallback.
*
* This function is called before a bind operation. If the BIND_DN is a user
@@ -550,7 +580,15 @@ static int pre_entry(Slapi_PBlock *pb)
}
if (is_service(bind_dn, &service) != 0) {
- return 0;
+ parent_dn = slapi_dn_parent(bind_dn);
+ rc |= is_user(parent_dn);
+ slapi_ch_free_string(&parent_dn);
+
+ if (rc != 0) {
+ return 0;
+ }
+
+ service = get_virtual_service(bind_dn);
}
result_dn = slapi_entry_get_dn(entry);