[prev in list] [next in list] [prev in thread] [next in thread] 

List:       fedora-directory-commits
Subject:    [389-commits] dirsrvtests/suites ldap/servers
From:       Noriko Hosoi <nhosoi () fedoraproject ! org>
Date:       2015-02-18 18:33:29
Message-ID: 20150218183329.5C9F060ED3 () fedorahosted ! org
[Download RAW message or body]

 dirsrvtests/suites/dynamic-plugins/plugin_tests.py |   83 ++++++
 ldap/servers/plugins/uiduniq/uid.c                 |  286 ++++++++++++++-------
 2 files changed, 275 insertions(+), 94 deletions(-)

New commits:
commit 430410d75446cdf58e6f020e1463b590abd870ab
Author: William B <william.e.brown@adelaide.edu.au>
Date:   Sun Feb 8 09:42:59 2015 +1030

    Ticket #48026 - Support for uniqueness plugin to enforce uniqueness on a set of \
attributes.  
    This allows defining multiple value to uniqueness-attribute-name, that will be
    taken as a set of values to maintain uniqueness for. IE mail, mailAlternate.
    If a value exists in mail, it may not exist in any other objects mail OR
    mailAlternate.
    
    https://fedorahosted.org/389/ticket/48026
    
    Reviewed by nhosoi@redhat.com.

diff --git a/dirsrvtests/suites/dynamic-plugins/plugin_tests.py \
b/dirsrvtests/suites/dynamic-plugins/plugin_tests.py index 43d0244..03aca80 100644
--- a/dirsrvtests/suites/dynamic-plugins/plugin_tests.py
+++ b/dirsrvtests/suites/dynamic-plugins/plugin_tests.py
@@ -296,6 +296,7 @@ def test_attruniq(inst, args=None):
                                      'cn': 'user 1',
                                      'uid': 'user1',
                                      'mail': 'user1@example.com',
+                                     'mailAlternateAddress' : \
'user1@alt.example.com',  'userpassword': 'password'})))
     except ldap.LDAPError, e:
         log.fatal('test_attruniq: Failed to add test user' + USER1_DN + ': error ' + \
e.message['desc']) @@ -346,6 +347,88 @@ def test_attruniq(inst, args=None):
         assert False
 
     ############################################################################
+    # Reconfigure plugin for mail and mailAlternateAddress
+    ############################################################################
+
+    try:
+        inst.modify_s('cn=' + PLUGIN_ATTR_UNIQUENESS + ',cn=plugins,cn=config',
+                      [(ldap.MOD_REPLACE, 'uniqueness-attribute-name', 'mail'), 
+                       (ldap.MOD_ADD, 'uniqueness-attribute-name',
+                        'mailAlternateAddress')])
+
+    except ldap.LDAPError, e:
+        log.error('test_attruniq: Failed to reconfigure plugin for "mail \
mailAlternateAddress": error ' + e.message['desc']) +        assert False
+
+    ############################################################################
+    # Test plugin - Add an entry, that has a duplicate "mail" value
+    ############################################################################
+
+    try:
+        inst.add_s(Entry((USER2_DN, {'objectclass': "top extensibleObject".split(),
+                                 'sn': '2',
+                                 'cn': 'user 2',
+                                 'uid': 'user2',
+                                 'mail': 'user1@example.com',
+                                 'userpassword': 'password'})))
+    except ldap.CONSTRAINT_VIOLATION:
+        pass
+    else:
+        log.error('test_attruniq: Adding of 3rd entry(mail) incorrectly succeeded')
+        assert False
+
+    ############################################################################
+    # Test plugin - Add an entry, that has a duplicate "mailAlternateAddress" value
+    ############################################################################
+
+    try:
+        inst.add_s(Entry((USER2_DN, {'objectclass': "top extensibleObject".split(),
+                                 'sn': '2',
+                                 'cn': 'user 2',
+                                 'uid': 'user2',
+                                 'mailAlternateAddress': 'user1@alt.example.com',
+                                 'userpassword': 'password'})))
+    except ldap.CONSTRAINT_VIOLATION:
+        pass
+    else:
+        log.error('test_attruniq: Adding of 4th entry(mailAlternateAddress) \
incorrectly succeeded') +        assert False
+
+    ############################################################################
+    # Test plugin - Add an entry, that has a duplicate "mail" value conflicting \
mailAlternateAddress +    \
############################################################################ +
+    try:
+        inst.add_s(Entry((USER2_DN, {'objectclass': "top extensibleObject".split(),
+                                 'sn': '2',
+                                 'cn': 'user 2',
+                                 'uid': 'user2',
+                                 'mail': 'user1@alt.example.com',
+                                 'userpassword': 'password'})))
+    except ldap.CONSTRAINT_VIOLATION:
+        pass
+    else:
+        log.error('test_attruniq: Adding of 5th entry(mailAlternateAddress) \
incorrectly succeeded') +        assert False
+
+    ############################################################################
+    # Test plugin - Add an entry, that has a duplicate "mailAlternateAddress" \
conflicting mail +    \
############################################################################ +
+    try:
+        inst.add_s(Entry((USER2_DN, {'objectclass': "top extensibleObject".split(),
+                                 'sn': '2',
+                                 'cn': 'user 2',
+                                 'uid': 'user2',
+                                 'mailAlternateAddress': 'user1@example.com',
+                                 'userpassword': 'password'})))
+    except ldap.CONSTRAINT_VIOLATION:
+        pass
+    else:
+        log.error('test_attruniq: Adding of 6th entry(mail) incorrectly succeeded')
+        assert False
+
+    ############################################################################
     # Test plugin dependency
     ############################################################################
 
diff --git a/ldap/servers/plugins/uiduniq/uid.c b/ldap/servers/plugins/uiduniq/uid.c
index 2120b4f..282f618 100644
--- a/ldap/servers/plugins/uiduniq/uid.c
+++ b/ldap/servers/plugins/uiduniq/uid.c
@@ -69,7 +69,7 @@ int ldap_quote_filter_value(
       int *outLen);
 
 
-static int search_one_berval(Slapi_DN *baseDN, const char *attrName,
+static int search_one_berval(Slapi_DN *baseDN, const char **attrNames,
 		const struct berval *value, const char *requiredObjectClass, Slapi_DN *target);
 
 /*
@@ -100,7 +100,8 @@ pluginDesc = {
 };
 static void* plugin_identity = NULL;
 typedef struct attr_uniqueness_config {
-        char *attr;
+        const char **attrs;
+        char *attr_friendly;
         Slapi_DN **subtrees;
         PRBool unique_in_all_subtrees;
         char *top_entry_oc;
@@ -128,7 +129,9 @@ free_uniqueness_config(struct attr_uniqueness_config *config)
 {
         int i;
         
-        slapi_ch_free_string((char **) &config->attr);
+        for (i = 0; config->attrs && config->attrs[i]; i++) {
+                slapi_ch_free_string((char **) &(config->attrs[i]));
+        }
         for (i = 0; config->subtrees && config->subtrees[i]; i++) {
                 slapi_sdn_free(&config->subtrees[i]);
         }
@@ -183,6 +186,8 @@ uniqueness_entry_to_config(Slapi_PBlock *pb, Slapi_Entry \
*config_entry)  char **argv = NULL;
         int rc = SLAPI_PLUGIN_SUCCESS;
         int i;
+        int attrLen = 0;
+        char *fp;
         int nb_subtrees = 0;
 
         if (config_entry == NULL) {
@@ -218,8 +223,18 @@ uniqueness_entry_to_config(Slapi_PBlock *pb, Slapi_Entry \
                *config_entry)
                  */
 
                 /* Attribute name of the attribute we are going to check value \
                uniqueness */
-                tmp_config->attr = slapi_entry_attr_get_charptr(config_entry, \
                ATTR_UNIQUENESS_ATTRIBUTE_NAME);
-                
+                values = slapi_entry_attr_get_charray(config_entry, \
ATTR_UNIQUENESS_ATTRIBUTE_NAME); +                if (values) {
+                        for (i = 0; values && values[i]; i++);
+                        tmp_config->attrs = (const char **) slapi_ch_calloc(i + 1, \
sizeof(char *)); +                        for (i = 0; values && values[i]; i++) {
+                                tmp_config->attrs[i] = slapi_ch_strdup(values[i]);
+                                slapi_log_error(SLAPI_LOG_PLUGIN, plugin_name, \
"Adding attribute %s to uniqueness set\n", tmp_config->attrs[i]); +                   \
} +                        slapi_ch_array_free(values);
+                        values = NULL;
+                }
+
                 /* Subtrees where uniqueness is tested  */
                 values = slapi_entry_attr_get_charray(config_entry, \
ATTR_UNIQUENESS_SUBTREES);  if (values) {
@@ -283,7 +298,8 @@ uniqueness_entry_to_config(Slapi_PBlock *pb, Slapi_Entry \
*config_entry)  }
                         
                         /* Store attrName in the config */
-                        tmp_config->attr = slapi_ch_strdup(attrName);
+                        tmp_config->attrs = (const char **) slapi_ch_calloc(1, \
sizeof(char *)); +                        tmp_config->attrs[0] = \
slapi_ch_strdup(attrName);  argc--;
                         argv++; /* First argument was attribute name and remaining \
are subtrees */  
@@ -323,7 +339,8 @@ uniqueness_entry_to_config(Slapi_PBlock *pb, Slapi_Entry \
                *config_entry)
                          *  - requiredObjectClass 
                          */
                         /* Store attrName in the config */
-                        tmp_config->attr = slapi_ch_strdup(attrName);
+                        tmp_config->attrs = (const char **) slapi_ch_calloc(1, \
sizeof(char *)); +                        tmp_config->attrs[0] = \
slapi_ch_strdup(attrName);  
                         /* There is no subtrees */
                         tmp_config->subtrees = NULL;
@@ -340,12 +357,25 @@ uniqueness_entry_to_config(Slapi_PBlock *pb, Slapi_Entry \
*config_entry)  }
         
         /* Time to check that the new configuration is valid */
-        if (tmp_config->attr == NULL) {
+        /* Check that we have 1 or more value */
+        if (tmp_config->attrs == NULL) {
                 slapi_log_error( SLAPI_LOG_FATAL, plugin_name, "Config info: \
attribute name not defined \n");  rc = SLAPI_PLUGIN_FAILURE;
                 goto done;
         }
-        
+        /* If the config is valid, prepare the friendly string for error messages */
+        for (i = 0; tmp_config->attrs && (tmp_config->attrs)[i]; i++) {
+            attrLen += strlen((tmp_config->attrs)[i]) + 1;
+        }
+        tmp_config->attr_friendly = (char *) slapi_ch_calloc(attrLen, sizeof(char \
*)); +        fp = tmp_config->attr_friendly;
+        for (i = 0; tmp_config->attrs && (tmp_config->attrs)[i]; i++) {
+            strcpy(fp, (tmp_config->attrs)[i] );
+            fp += strlen((tmp_config->attrs)[i]);
+            strcpy(fp, " ");
+            fp++;
+        }
+
         if (tmp_config->subtrees == NULL) {
                 /* Uniqueness is enforced on entries matching objectclass */
                 if (tmp_config->subtree_entries_oc == NULL) {
@@ -407,20 +437,39 @@ uid_op_error(int internal_error)
  */
 
 static char *
-create_filter(const char *attribute, const struct berval *value, const char \
*requiredObjectClass) +create_filter(const char **attributes, const struct berval \
*value, const char *requiredObjectClass)  {
   char *filter;
   char *fp;
   char *max;
-  int attrLen;
+  int  *attrLen;
+  int totalAttrLen = 0;
+  int attrCount = 0;
   int valueLen;
   int classLen = 0;
   int filterLen;
+  int i = 0;
 
-  PR_ASSERT(attribute);
+  PR_ASSERT(attributes);
 
   /* Compute the length of the required buffer */
-  attrLen = strlen(attribute);
+  for (attrCount = 0; attributes && attributes[attrCount]; attrCount++);
+  attrCount++;
+  attrLen = (int *) slapi_ch_calloc(attrCount, sizeof(int));
+  for (i = 0; attributes && attributes[i]; i++) {
+      attrLen[i] += strlen(attributes[i]);
+      totalAttrLen += attrLen[i];
+  }
+
+  /* if attrCount is 1, attrLen is already corect for usage.*/
+  if (attrCount > 1) {
+    /* Filter will be (|(attr=value)(attr=value)) */
+    /* 3 for the (| ) */
+    /* 3 for each attr for (=) not in attr or value */
+    totalAttrLen += 3 + (attrCount * 3);
+  } else {
+    totalAttrLen += 3;
+  }
 
   if (ldap_quote_filter_value(value->bv_val, 
 	value->bv_len, 0, 0, &valueLen))
@@ -428,10 +477,10 @@ create_filter(const char *attribute, const struct berval \
*value, const char *req  
   if (requiredObjectClass) {
     classLen = strlen(requiredObjectClass);
-    /* "(&(objectClass=)())" == 19 */
-    filterLen = attrLen + 1 + valueLen + classLen + 19 + 1;
+    /* "(&(objectClass=)<Filter here>)" == 17 */
+    filterLen = totalAttrLen + 1 + (valueLen * attrCount) + classLen + 17 + 1;
   } else {
-    filterLen = attrLen + 1 + valueLen + 1;
+    filterLen = totalAttrLen + 1 + (valueLen * attrCount) + 1;
   }
 
   /* Allocate the buffer */
@@ -446,30 +495,58 @@ create_filter(const char *attribute, const struct berval \
*value, const char *req  strcpy(fp, requiredObjectClass);
     fp += classLen;
     *fp++ = ')';
-    *fp++ = '(';
   }
 
-  /* Place attribute name in filter */
-  strcpy(fp, attribute);
-  fp += attrLen;
+  if (attrCount == 1) {
+      *fp++ = '(';
+      /* Place attribute name in filter */
+      strcpy(fp, attributes[0]);
+      fp += attrLen[0];
 
-  /* Place comparison operator */
-  *fp++ = '=';
+      /* Place comparison operator */
+      *fp++ = '=';
 
-  /* Place value in filter */
-  if (ldap_quote_filter_value(value->bv_val, value->bv_len,
-    fp, max-fp, &valueLen)) { slapi_ch_free((void**)&filter); return 0; }
-  fp += valueLen;
+      /* Place value in filter */
+      if (ldap_quote_filter_value(value->bv_val, value->bv_len,
+        fp, max-fp, &valueLen)) { slapi_ch_free((void**)&filter); return 0; }
+      fp += valueLen;
+      *fp++ = ')';
+  } else {
+      strcpy(fp, "(|");
+      fp += 2;
+
+      for (i = 0; attributes && attributes[i]; i++) {
+          strcpy(fp, "(");
+          fp += 1;
+          /* Place attribute name in filter */
+          strcpy(fp, attributes[i]);
+          fp += attrLen[i];
+
+          /* Place comparison operator */
+          *fp++ = '=';
+
+          /* Place value in filter */
+          if (ldap_quote_filter_value(value->bv_val, value->bv_len,
+            fp, max-fp, &valueLen)) { slapi_ch_free((void**)&filter); return 0; }
+          fp += valueLen;
+
+          strcpy(fp, ")");
+          fp += 1;
+      }
+      strcpy(fp, ")");
+      fp += 1;
+  }
 
   /* Close AND expression if a requiredObjectClass was set */
   if (requiredObjectClass) {
     *fp++ = ')';
-    *fp++ = ')';
   }
 
   /* Terminate */
   *fp = 0;
 
+  slapi_ch_free((void **) &attrLen);
+
   return filter;
 }
 
@@ -490,15 +567,16 @@ create_filter(const char *attribute, const struct berval \
                *value, const char *req
  *   LDAP_OPERATIONS_ERROR - a server failure.
  */
 static int
-search(Slapi_DN *baseDN, const char *attrName, Slapi_Attr *attr,
+search(Slapi_DN *baseDN, const char **attrNames, Slapi_Attr *attr,
   struct berval **values, const char *requiredObjectClass,
   Slapi_DN *target)
 {
   int result;
 
 #ifdef DEBUG
+    /* Fix this later to print all the attr names */
     slapi_log_error(SLAPI_LOG_PLUGIN, plugin_name,
-                    "SEARCH baseDN=%s attr=%s target=%s\n", \
slapi_sdn_get_dn(baseDN), attrName,  +                    "SEARCH baseDN=%s attr=%s \
target=%s\n", slapi_sdn_get_dn(baseDN), attrNames[0],   \
target?slapi_sdn_get_dn(target):"None");  #endif
 
@@ -524,7 +602,7 @@ search(Slapi_DN *baseDN, const char *attrName, Slapi_Attr *attr,
 		vhint != -1 && LDAP_SUCCESS == result;
 		vhint = slapi_attr_next_value( attr, vhint, &v ))
 	{
-	  result = search_one_berval(baseDN, attrName,
+	  result = search_one_berval(baseDN, attrNames,
 					slapi_value_get_berval(v),
 					requiredObjectClass, target);
 	}
@@ -533,7 +611,7 @@ search(Slapi_DN *baseDN, const char *attrName, Slapi_Attr *attr,
   {
 	for (;*values != NULL && LDAP_SUCCESS == result; values++)
 	{
-	  result = search_one_berval(baseDN, attrName, *values, requiredObjectClass,
+	  result = search_one_berval(baseDN, attrNames, *values, requiredObjectClass,
 					target);
 	}
   }
@@ -548,7 +626,7 @@ search(Slapi_DN *baseDN, const char *attrName, Slapi_Attr *attr,
 
 
 static int
-search_one_berval(Slapi_DN *baseDN, const char *attrName,
+search_one_berval(Slapi_DN *baseDN, const char **attrNames,
 		const struct berval *value, const char *requiredObjectClass,
 		Slapi_DN *target)
 {
@@ -572,7 +650,7 @@ search_one_berval(Slapi_DN *baseDN, const char *attrName,
       static char *attrs[] = { "1.1", 0 };
 
       /* Create the filter - this needs to be freed */
-      filter = create_filter(attrName, value, requiredObjectClass);
+      filter = create_filter(attrNames, value, requiredObjectClass);
 
 #ifdef DEBUG
       slapi_log_error(SLAPI_LOG_PLUGIN, plugin_name,
@@ -656,7 +734,7 @@ search_one_berval(Slapi_DN *baseDN, const char *attrName,
  *   LDAP_OPERATIONS_ERROR - a server failure.
  */
 static int
-searchAllSubtrees(Slapi_DN **subtrees, const char *attrName,
+searchAllSubtrees(Slapi_DN **subtrees, const char **attrNames,
   Slapi_Attr *attr, struct berval **values, const char *requiredObjectClass,
   Slapi_DN *dn, PRBool unique_in_all_subtrees)
 {
@@ -697,7 +775,7 @@ searchAllSubtrees(Slapi_DN **subtrees, const char *attrName,
      * worry about that here.
      */
     if (unique_in_all_subtrees || slapi_sdn_issuffix(dn, sufdn)) {
-      result = search(sufdn, attrName, attr, values, requiredObjectClass, dn);
+      result = search(sufdn, attrNames, attr, values, requiredObjectClass, dn);
       if (result) break;
     }
   }
@@ -785,7 +863,7 @@ getArguments(Slapi_PBlock *pb, char **attrName, char \
                **markerObjectClass,
  *   LDAP_OPERATIONS_ERROR - a server failure.
  */
 static int
-findSubtreeAndSearch(Slapi_DN *parentDN, const char *attrName, Slapi_Attr *attr,
+findSubtreeAndSearch(Slapi_DN *parentDN, const char **attrNames, Slapi_Attr *attr,
   struct berval **values, const char *requiredObjectClass, Slapi_DN *target,
   const char *markerObjectClass)
 {
@@ -804,7 +882,7 @@ findSubtreeAndSearch(Slapi_DN *parentDN, const char *attrName, \
                Slapi_Attr *attr,
            * Do the search.   There is no entry that is allowed
            * to have the attribute already.
            */
-          result = search(curpar, attrName, attr, values, requiredObjectClass,
+          result = search(curpar, attrNames, attr, values, requiredObjectClass,
                           target);
           break;
         }
@@ -827,7 +905,8 @@ preop_add(Slapi_PBlock *pb)
 {
   int result;
   char *errtext = NULL;
-  char *attrName = NULL;
+  const char **attrNames = NULL;
+  char * attr_friendly = NULL;
 
 #ifdef DEBUG
   slapi_log_error(SLAPI_LOG_PLUGIN, plugin_name, "ADD begin\n");
@@ -848,6 +927,7 @@ preop_add(Slapi_PBlock *pb)
     Slapi_Entry *e;
     Slapi_Attr *attr;
     struct attr_uniqueness_config *config = NULL;
+    int i = 0;
 
         /*
          * If this is a replication update, just be a noop.
@@ -868,9 +948,10 @@ preop_add(Slapi_PBlock *pb)
         /*
          * Get the arguments
          */
-        attrName = config->attr;
+        attrNames = config->attrs;
         markerObjectClass = config->top_entry_oc;
         requiredObjectClass = config->subtree_entries_oc;
+        attr_friendly = config->attr_friendly;
 
     /*
      * Get the target DN for this add operation
@@ -889,9 +970,6 @@ preop_add(Slapi_PBlock *pb)
         err = slapi_pblock_get(pb, SLAPI_ADD_ENTRY, &e);
         if (err) { result = uid_op_error(52); break; }
 
-        err = slapi_entry_attr_find(e, attrName, &attr);
-        if (err) break;  /* no unique attribute */
-
         /*
          * Check if it contains the required object class
          */
@@ -904,22 +982,30 @@ preop_add(Slapi_PBlock *pb)
           }
         }
 
-        /*
-         * Passed all the requirements - this is an operation we
-         * need to enforce uniqueness on. Now find all parent entries
-         * with the marker object class, and do a search for each one.
-         */
-        if (NULL != markerObjectClass)
-        {
-          /* Subtree defined by location of marker object class */
-                result = findSubtreeAndSearch(sdn, attrName, attr, NULL,
-                                              requiredObjectClass, sdn,
-                                              markerObjectClass);
-        } else
-        {
-          /* Subtrees listed on invocation line */
-          result = searchAllSubtrees(config->subtrees, attrName, attr, NULL,
-                                     requiredObjectClass, sdn, \
config->unique_in_all_subtrees); +        for (i = 0; attrNames && attrNames[i]; i++) \
{ +            err = slapi_entry_attr_find(e, attrNames[i], &attr);
+            if (!err) {
+                /*
+                 * Passed all the requirements - this is an operation we
+                 * need to enforce uniqueness on. Now find all parent entries
+                 * with the marker object class, and do a search for each one.
+                 */
+                if (NULL != markerObjectClass)
+                {
+                  /* Subtree defined by location of marker object class */
+                        result = findSubtreeAndSearch(sdn, attrNames, attr, NULL,
+                                                      requiredObjectClass, sdn,
+                                                      markerObjectClass);
+                } else
+                {
+                  /* Subtrees listed on invocation line */
+                  result = searchAllSubtrees(config->subtrees, attrNames, attr, \
NULL, +                                             requiredObjectClass, sdn, \
config->unique_in_all_subtrees); +                }
+                if (result != LDAP_SUCCESS) {
+                    break;
+                }
+            }
         }
   END
 
@@ -929,7 +1015,7 @@ preop_add(Slapi_PBlock *pb)
       "ADD result %d\n", result);
 
     if (result == LDAP_CONSTRAINT_VIOLATION) {
-      errtext = slapi_ch_smprintf(moreInfo, attrName);
+      errtext = slapi_ch_smprintf(moreInfo, attr_friendly);
     } else {
       errtext = slapi_ch_strdup("Error checking for attribute uniqueness.");
     }
@@ -971,8 +1057,9 @@ preop_modify(Slapi_PBlock *pb)
   LDAPMod **checkmods = NULL;
   int checkmodsCapacity = 0;
   char *errtext = NULL;
-  char *attrName = NULL;
+  const char **attrNames = NULL;
   struct attr_uniqueness_config *config = NULL;
+  char *attr_friendly = NULL;
 
 #ifdef DEBUG
     slapi_log_error(SLAPI_LOG_PLUGIN, plugin_name,
@@ -989,6 +1076,7 @@ preop_modify(Slapi_PBlock *pb)
     LDAPMod *mod;
     Slapi_DN *sdn = NULL;
     int isupdatedn;
+    int i = 0;
 
     /*
      * If this is a replication update, just be a noop.
@@ -1009,9 +1097,10 @@ preop_modify(Slapi_PBlock *pb)
     /*
      * Get the arguments
      */
-    attrName = config->attr;
+    attrNames = config->attrs;
     markerObjectClass = config->top_entry_oc;
     requiredObjectClass = config->subtree_entries_oc;
+    attr_friendly = config->attr_friendly;
 
         
     err = slapi_pblock_get(pb, SLAPI_MODIFY_MODS, &mods);
@@ -1032,14 +1121,16 @@ preop_modify(Slapi_PBlock *pb)
     for(;mods && *mods;mods++)
     {
         mod = *mods;
-        if ((slapi_attr_type_cmp(mod->mod_type, attrName, 1) == 0) && /* mod \
                contains target attr */
-            (mod->mod_op & LDAP_MOD_BVALUES) && /* mod is bval encoded (not string \
                val) */
-            (mod->mod_bvalues && mod->mod_bvalues[0]) && /* mod actually contains \
                some values */
-            (SLAPI_IS_MOD_ADD(mod->mod_op) || /* mod is add */
-             SLAPI_IS_MOD_REPLACE(mod->mod_op))) /* mod is replace */
-        {
-          addMod(&checkmods, &checkmodsCapacity, &modcount, mod);
-        }
+        for (i = 0; attrNames && attrNames[i]; i++) {
+          if ((slapi_attr_type_cmp(mod->mod_type, attrNames[i], 1) == 0) && /* mod \
contains target attr */ +              (mod->mod_op & LDAP_MOD_BVALUES) && /* mod is \
bval encoded (not string val) */ +              (mod->mod_bvalues && \
mod->mod_bvalues[0]) && /* mod actually contains some values */ +              \
(SLAPI_IS_MOD_ADD(mod->mod_op) || /* mod is add */ +               \
SLAPI_IS_MOD_REPLACE(mod->mod_op))) /* mod is replace */ +          {
+            addMod(&checkmods, &checkmodsCapacity, &modcount, mod);
+          }
+       }
     }
     if (modcount == 0) {
         break; /* no mods to check, we are done */
@@ -1071,13 +1162,13 @@ preop_modify(Slapi_PBlock *pb)
         if (NULL != markerObjectClass)
         {
             /* Subtree defined by location of marker object class */
-            result = findSubtreeAndSearch(sdn, attrName, NULL, 
+            result = findSubtreeAndSearch(sdn, attrNames, NULL, 
                                           mod->mod_bvalues, requiredObjectClass,
                                           sdn, markerObjectClass);
         } else
         {
             /* Subtrees listed on invocation line */
-            result = searchAllSubtrees(config->subtrees, attrName, NULL,
+            result = searchAllSubtrees(config->subtrees, attrNames, NULL,
                                        mod->mod_bvalues, requiredObjectClass, sdn, \
config->unique_in_all_subtrees);  }
     }
@@ -1091,7 +1182,7 @@ preop_modify(Slapi_PBlock *pb)
       "MODIFY result %d\n", result);
 
     if (result == LDAP_CONSTRAINT_VIOLATION) {
-      errtext = slapi_ch_smprintf(moreInfo, attrName);
+      errtext = slapi_ch_smprintf(moreInfo, attr_friendly);
     } else {
       errtext = slapi_ch_strdup("Error checking for attribute uniqueness.");
     }
@@ -1119,7 +1210,7 @@ preop_modrdn(Slapi_PBlock *pb)
   Slapi_Entry *e = NULL;
   Slapi_Value *sv_requiredObjectClass = NULL;
   char *errtext = NULL;
-  char *attrName = NULL;
+  const char **attrNames = NULL;
   struct attr_uniqueness_config *config = NULL;
 
 #ifdef DEBUG
@@ -1137,6 +1228,7 @@ preop_modrdn(Slapi_PBlock *pb)
     int deloldrdn = 0;
     int isupdatedn;
     Slapi_Attr *attr;
+    int i = 0;
 
         /*
          * If this is a replication update, just be a noop.
@@ -1157,7 +1249,7 @@ preop_modrdn(Slapi_PBlock *pb)
         /*
          * Get the arguments
          */
-        attrName = config->attr;
+        attrNames = config->attrs;
         markerObjectClass = config->top_entry_oc;
         requiredObjectClass = config->subtree_entries_oc;
 
@@ -1211,11 +1303,6 @@ preop_modrdn(Slapi_PBlock *pb)
     err = slapi_entry_rename(e, rdn, deloldrdn, superior);
     if (err != LDAP_SUCCESS) { result = uid_op_error(36); break; }
 
-        /*
-         * Find any unique attribute data in the new RDN
-         */
-        err = slapi_entry_attr_find(e, attrName, &attr);
-        if (err) break;  /* no UID attribute */
 
         /*
          * Check if it has the required object class
@@ -1224,21 +1311,32 @@ preop_modrdn(Slapi_PBlock *pb)
             !slapi_entry_attr_has_syntax_value(e, SLAPI_ATTR_OBJECTCLASS, \
sv_requiredObjectClass)) { break; }  
         /*
-         * Passed all the requirements - this is an operation we
-         * need to enforce uniqueness on. Now find all parent entries
-         * with the marker object class, and do a search for each one.
+         * Find any unique attribute data in the new RDN
          */
-        if (NULL != markerObjectClass)
-        {
-          /* Subtree defined by location of marker object class */
-                result = findSubtreeAndSearch(slapi_entry_get_sdn(e), attrName, \
                attr, NULL,
-                                              requiredObjectClass, sdn,
-                                              markerObjectClass);
-        } else
-        {
-          /* Subtrees listed on invocation line */
-          result = searchAllSubtrees(config->subtrees, attrName, attr, NULL,
-                                     requiredObjectClass, sdn, \
config->unique_in_all_subtrees); +        for (i = 0; attrNames && attrNames[i]; i++) \
{ +            err = slapi_entry_attr_find(e, attrNames[i], &attr);
+            if (!err) {
+                /*
+                 * Passed all the requirements - this is an operation we
+                 * need to enforce uniqueness on. Now find all parent entries
+                 * with the marker object class, and do a search for each one.
+                 */
+                if (NULL != markerObjectClass)
+                {
+                  /* Subtree defined by location of marker object class */
+                        result = findSubtreeAndSearch(slapi_entry_get_sdn(e), \
attrNames, attr, NULL, +                                                      \
requiredObjectClass, sdn, +                                                      \
markerObjectClass); +                } else
+                {
+                  /* Subtrees listed on invocation line */
+                  result = searchAllSubtrees(config->subtrees, attrNames, attr, \
NULL, +                                             requiredObjectClass, sdn, \
config->unique_in_all_subtrees); +                }
+                if (result != LDAP_SUCCESS) {
+                    break;
+                }
+            }
         }
   END
   /* Clean-up */
@@ -1251,7 +1349,7 @@ preop_modrdn(Slapi_PBlock *pb)
       "MODRDN result %d\n", result);
 
     if (result == LDAP_CONSTRAINT_VIOLATION) {
-      errtext = slapi_ch_smprintf(moreInfo, attrName);
+      errtext = slapi_ch_smprintf(moreInfo, config->attr_friendly);
     } else {
       errtext = slapi_ch_strdup("Error checking for attribute uniqueness.");
     }


--
389 commits mailing list
389-commits@lists.fedoraproject.org
https://admin.fedoraproject.org/mailman/listinfo/389-commits


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic