From 92fbcbe2c3f4476cc4b6373bb52ef4663ea7e4c4 Mon Sep 17 00:00:00 2001 From: Ludwig Krispenz Date: Fri, 27 Jun 2014 15:20:25 +0200 Subject: [PATCH 231/234] Ticket 47821 - deref plugin cannot handle complex acis Bug Description: the deref plugin does not return attributes if the access depends on rules requireing the entry Fix Description: do the access check after the entry is retrieved https://fedorahosted.org/389/ticket/47821 Reviewed by: mark, thanks Conflicts: ldap/servers/plugins/deref/deref.c (cherry picked from commit ed487614f094a902afa7299e2c98f4cd8d02fe96) --- ldap/servers/plugins/deref/deref.c | 115 +++++++++++++++++++------------------ 1 file changed, 59 insertions(+), 56 deletions(-) diff --git a/ldap/servers/plugins/deref/deref.c b/ldap/servers/plugins/deref/deref.c index 6e4d4ec..c6630df 100644 --- a/ldap/servers/plugins/deref/deref.c +++ b/ldap/servers/plugins/deref/deref.c @@ -597,14 +597,10 @@ deref_do_deref_attr(Slapi_PBlock *pb, BerElement *ctrlber, const char *derefdn, Slapi_Entry **entries = NULL; int rc; - if (deref_check_access(pb, NULL, derefdn, attrs, &retattrs, - (SLAPI_ACL_SEARCH|SLAPI_ACL_READ))) { - slapi_log_error(SLAPI_LOG_PLUGIN, DEREF_PLUGIN_SUBSYSTEM, - "The client does not have permission to read the requested " - "attributes in entry %s\n", derefdn); - return; - } - +/* If the access check on the attributes is done without retrieveing the entry + * it cannot handle acis which need teh entry, eg to apply a targetfilter rule + * So the determination of attrs which can be dereferenced is delayed + */ derefpb = slapi_pblock_new(); slapi_search_internal_set_pb(derefpb, derefdn, LDAP_SCOPE_BASE, "(objectclass=*)", retattrs, 0, @@ -623,61 +619,68 @@ deref_do_deref_attr(Slapi_PBlock *pb, BerElement *ctrlber, const char *derefdn, } else { int ii; int needattrvals = 1; /* need attrvals sequence? */ - for (ii = 0; retattrs[ii]; ++ii) { - Slapi_Value *sv; - int idx = 0; - Slapi_ValueSet* results = NULL; - int type_name_disposition = 0; - char* actual_type_name = NULL; - int flags = 0; - int buffer_flags = 0; - int needpartialattr = 1; /* need PartialAttribute sequence? */ - int needvalsset = 1; - - if (is_type_forbidden(retattrs[ii])) { - slapi_log_error(SLAPI_LOG_PLUGIN, DEREF_PLUGIN_SUBSYSTEM, - "skip forbidden attribute [%s]\n", derefdn); - continue; - } + if (deref_check_access(pb, entries[0], derefdn, attrs, &retattrs, + (SLAPI_ACL_SEARCH|SLAPI_ACL_READ))) { + slapi_log_error(SLAPI_LOG_PLUGIN, DEREF_PLUGIN_SUBSYSTEM, + "The client does not have permission to read the requested " + "attributes in entry %s\n", derefdn); + } else { + for (ii = 0; retattrs[ii]; ++ii) { + Slapi_Value *sv; + int idx = 0; + Slapi_ValueSet* results = NULL; + int type_name_disposition = 0; + char* actual_type_name = NULL; + int flags = 0; + int buffer_flags = 0; + int needpartialattr = 1; /* need PartialAttribute sequence? */ + int needvalsset = 1; + + if (is_type_forbidden(retattrs[ii])) { + slapi_log_error(SLAPI_LOG_PLUGIN, DEREF_PLUGIN_SUBSYSTEM, + "skip forbidden attribute [%s]\n", derefdn); + continue; + } - deref_get_values(entries[0], retattrs[ii], &results, &type_name_disposition, - &actual_type_name, flags, &buffer_flags); + deref_get_values(entries[0], retattrs[ii], &results, &type_name_disposition, + &actual_type_name, flags, &buffer_flags); - if (results) { - idx = slapi_valueset_first_value(results, &sv); - } - for (; results && sv; idx = slapi_valueset_next_value(results, idx, &sv)) { - const struct berval *bv = slapi_value_get_berval(sv); - if (needattrvals) { - /* we have at least one attribute with values in - DerefRes.attrVals */ - /* attrVals is OPTIONAL - only added if there are - any values to send */ - ber_printf(ctrlber, "t{", (LBER_CLASS_CONTEXT|LBER_CONSTRUCTED)); - needattrvals = 0; + if (results) { + idx = slapi_valueset_first_value(results, &sv); } - if (needpartialattr) { - /* This attribute in attrVals has values */ - ber_printf(ctrlber, "{s", retattrs[ii]); - needpartialattr = 0; + for (; results && sv; idx = slapi_valueset_next_value(results, idx, &sv)) { + const struct berval *bv = slapi_value_get_berval(sv); + if (needattrvals) { + /* we have at least one attribute with values in + DerefRes.attrVals */ + /* attrVals is OPTIONAL - only added if there are + any values to send */ + ber_printf(ctrlber, "t{", (LBER_CLASS_CONTEXT|LBER_CONSTRUCTED)); + needattrvals = 0; + } + if (needpartialattr) { + /* This attribute in attrVals has values */ + ber_printf(ctrlber, "{s", retattrs[ii]); + needpartialattr = 0; + } + if (needvalsset) { + /* begin the vals SET of values for this attribute */ + ber_printf(ctrlber, "["); + needvalsset = 0; + } + ber_printf(ctrlber, "O", bv); + } /* for each value in retattrs[ii] */ + deref_values_free(&results, &actual_type_name, buffer_flags); + if (needvalsset == 0) { + ber_printf(ctrlber, "]"); } - if (needvalsset) { - /* begin the vals SET of values for this attribute */ - ber_printf(ctrlber, "["); - needvalsset = 0; + if (needpartialattr == 0) { + ber_printf(ctrlber, "}"); } - ber_printf(ctrlber, "O", bv); - } /* for each value in retattrs[ii] */ - deref_values_free(&results, &actual_type_name, buffer_flags); - if (needvalsset == 0) { - ber_printf(ctrlber, "]"); - } - if (needpartialattr == 0) { + } /* for each attr in retattrs */ + if (needattrvals == 0) { ber_printf(ctrlber, "}"); } - } /* for each attr in retattrs */ - if (needattrvals == 0) { - ber_printf(ctrlber, "}"); } } } else { /* nothing */ -- 1.8.1.4