From 864d0352619afa1887db553c2e61df61ddb121ee Mon Sep 17 00:00:00 2001 From: Alexander Sulfrian Date: Tue, 15 Dec 2015 22:02:43 +0100 Subject: Add pre_entry plugin to fake the DN of the search results --- service_passwords.c | 130 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 130 insertions(+) diff --git a/service_passwords.c b/service_passwords.c index 50749db..fdd4bbd 100644 --- a/service_passwords.c +++ b/service_passwords.c @@ -96,6 +96,53 @@ fail1: return rc; } +static char* is_service_dn(const char *dn) +{ + char *service = NULL; + + Slapi_Entry *entry = NULL; + char *attrs[] = { "cn", NULL }; + Slapi_Attr *attr = NULL; + struct berval **cn = NULL; + + int rc = 0; + + /* TODO: check parent dn */ + + rc |= get_entry(dn, attrs, &entry); + if (rc != 0 || entry == NULL) { + /* dn not found */ + service = NULL; + goto fail1; + } + + rc |= slapi_entry_attr_find(entry, "cn", &attr); + if (rc != 0 || attr == NULL) { + /* no cn attribute */ + service = NULL; + goto fail1; + } + + rc |= slapi_attr_get_values(attr, &cn); + if (rc != 0 || cn == NULL) { + /* no value in cn attribute */ + service = NULL; + goto fail1; + } + + if (*cn == NULL) { + service = NULL; + goto fail1; + } + + service = slapi_ch_strdup((*cn)->bv_val); + +fail1: + slapi_entry_free(entry); + + return service; +} + static int auth(char *dn, struct berval *credentials) { char *attrs[] = { "userPassword", NULL }; @@ -248,6 +295,88 @@ static int pre_bind(Slapi_PBlock *pb) return rc; } +static int pre_entry(Slapi_PBlock *pb) +{ + char *bind_dn; + char *auth_method; + Slapi_Entry *entry; + Slapi_Operation *op; + int is_replication; + int is_internal; + + char *service; + char *parent_dn = NULL; + char rdn[255]; + const char *result_dn = NULL; + char *new_dn = NULL; + Slapi_Entry *new_entry; + + int rc = 0; + char fn[] = "pre_entry in service_passwords plug-in"; + + rc |= slapi_pblock_get(pb, SLAPI_CONN_DN, &bind_dn); + rc |= slapi_pblock_get(pb, SLAPI_CONN_AUTHMETHOD, &auth_method); + rc |= slapi_pblock_get(pb, SLAPI_SEARCH_RESULT_ENTRY, &entry); + rc |= slapi_pblock_get(pb, SLAPI_OPERATION, &op); + 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 (strcmp(auth_method, SLAPD_AUTH_NONE) == 0) { + /* only handle authenticated searches */ + return 0; + } + + if (slapi_op_get_type(op) != SLAPI_OPERATION_SEARCH) { + return 0; + } + + service = is_service_dn(bind_dn); + if (service == NULL) { + goto fail1; + } + + result_dn = slapi_entry_get_dn(entry); + + /* ignore service_password entries */ + parent_dn = slapi_dn_parent(result_dn); + if (dn_contains_uid(parent_dn) == 0) { + rc = -1; + goto fail1; + } + slapi_ch_free_string(&parent_dn); + + /* modify the dn of the returned entry */ + if (dn_contains_uid(result_dn) == 0) { + /* TODO: style */ + snprintf(rdn, 254, "cn=%s", service); + new_dn = slapi_dn_plus_rdn(result_dn, rdn); + new_entry = slapi_entry_dup(entry); + slapi_entry_set_dn(new_entry, new_dn); + slapi_ch_free_string(&new_dn); + slapi_pblock_set(pb, SLAPI_SEARCH_RESULT_ENTRY, new_entry); + } + +fail1: + slapi_ch_free_string(&service); + + return rc; +} + Slapi_PluginDesc bindpdesc = { .spd_id = "service_passwords", .spd_vendor = "spline", @@ -263,6 +392,7 @@ int service_passwords_init(Slapi_PBlock *pb) rc |= slapi_pblock_set(pb, SLAPI_PLUGIN_VERSION, SLAPI_PLUGIN_CURRENT_VERSION); 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_get(pb, SLAPI_PLUGIN_IDENTITY, &plugin_id); return rc; } -- cgit v1.2.3-1-g7c22