diff options
-rw-r--r-- | service_passwords.c | 40 |
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); |