summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNathan Kinder <nkinder@redhat.com>2010-10-14 08:51:57 -0700
committerNathan Kinder <nkinder@redhat.com>2010-10-14 12:23:21 -0700
commit032790e3bea8b4b61372a5b84926c83da2e03eef (patch)
tree712ee6a78b08cd41192ab5267b67641fc284096c
parent6b9f1aac9e0e5059e10e0ed92e6e8d9c4d5f4253 (diff)
downloadds-032790e3bea8b4b61372a5b84926c83da2e03eef.tar.gz
ds-032790e3bea8b4b61372a5b84926c83da2e03eef.tar.xz
ds-032790e3bea8b4b61372a5b84926c83da2e03eef.zip
Bug 555955 - Allow CoS values to be merged
This patch adds the ability for CoS values to be merged and create multi-valued attributes. One can append "merge-schemes" the the end of the cosAttribute value in a definition entry to allow values to be merged. With a single indirect CoS definition, a merge will make CoS use each specifier attribute value in the target entry to look for CoS values in each of the found template entries. All of these values will then be applied to the target entry (with the exception of duplicate values). With multiple indirect CoS definitions for the same attribute, setting merge mode for all definitions will cause all of the definitions to be used to find the values to apply to the target entry. If merge-schemes is not defined for all of these definitions, the result is undefined (values from the first found CoS definition will be applied).
-rw-r--r--ldap/servers/plugins/cos/cos_cache.c75
1 files changed, 67 insertions, 8 deletions
diff --git a/ldap/servers/plugins/cos/cos_cache.c b/ldap/servers/plugins/cos/cos_cache.c
index db99586c..971249c3 100644
--- a/ldap/servers/plugins/cos/cos_cache.c
+++ b/ldap/servers/plugins/cos/cos_cache.c
@@ -2367,9 +2367,10 @@ static int cos_cache_query_attr(cos_cache *ptheCache, vattr_context *context, Sl
/** class of service specifier **/
/*
- now we need to iterate through the attributes to discover
+ Now we need to iterate through the attributes to discover
if one fits all the criteria, we'll take the first that does
- and blow off the rest
+ and blow off the rest unless the definition has merge-scheme
+ set.
*/
do
{
@@ -2397,8 +2398,9 @@ static int cos_cache_query_attr(cos_cache *ptheCache, vattr_context *context, Sl
continue;
}
- /* is this entry a child of the target tree(s)? */
- while(hit == 0 && pTargetTree)
+ /* If we haven't found a hit yet, or if we are in merge mode, look for
+ * hits. We only check if this entry is a child of the target tree(s). */
+ while((hit == 0 || merge_mode) && pTargetTree)
{
{
int rc = 0;
@@ -2459,16 +2461,73 @@ static int cos_cache_query_attr(cos_cache *ptheCache, vattr_context *context, Sl
Note: we support one dn only, the result of multiple pointers is undefined
*/
Slapi_Value *indirectdn;
+ Slapi_ValueSet *tmp_vals = NULL;
int pointer_flags = 0;
+ int hint = 0;
- slapi_valueset_first_value( pAttrSpecs, &indirectdn );
+ hint = slapi_valueset_first_value( pAttrSpecs, &indirectdn );
if(props)
pointer_flags = *props;
- if( indirectdn != NULL &&
- !cos_cache_follow_pointer( context, (char*)slapi_value_get_string(indirectdn), type, out_attr, test_this, result, pointer_flags))
- hit = 1;
+ while (indirectdn != NULL)
+ {
+ if (cos_cache_follow_pointer( context, (char*)slapi_value_get_string(indirectdn),
+ type, &tmp_vals, test_this, result, pointer_flags) == 0)
+ {
+ hit = 1;
+ /* If the caller requested values, set them. We need
+ * to append values when we follow multiple pointers DNs. */
+ if (out_attr && tmp_vals)
+ {
+ if (*out_attr)
+ {
+ Slapi_Attr *attr = NULL;
+ Slapi_Value *val = NULL;
+ int idx = 0;
+
+ /* Create an attr to use for duplicate detection. */
+ attr = slapi_attr_new();
+ slapi_attr_init(attr, type);
+
+ /* Copy any values into out_attr if they don't already exist. */
+ for (idx = slapi_valueset_first_value(tmp_vals, &val);
+ val && (idx != -1);
+ idx = slapi_valueset_next_value(tmp_vals, idx, &val))
+ {
+ if (slapi_valueset_find(attr, *out_attr, val) == NULL)
+ {
+ slapi_valueset_add_value(*out_attr, val);
+ }
+ }
+
+ slapi_attr_free(&attr);
+ slapi_valueset_free(tmp_vals);
+ tmp_vals = NULL;
+ } else {
+ *out_attr = tmp_vals;
+ tmp_vals = NULL;
+ }
+ }
+ }
+
+ /* If this definition has merge-scheme set, we
+ * need to follow the rest of the pointers. */
+ if (pAttr->attr_cos_merge)
+ {
+ hint = slapi_valueset_next_value(pAttrSpecs, hint, &indirectdn);
+ } else {
+ indirectdn = NULL;
+ }
+ }
+
+ /* If merge-scheme is specified, set merge mode. This will allow
+ * us to merge in values from other CoS definitions for this attr. */
+ if (pAttr->attr_cos_merge)
+ {
+ merge_mode = 1;
+ attr_matched_index = attr_index;
+ }
}
else
{