From 8f9653033c8b7ede6faa00de7ce84185ab26fc5b Mon Sep 17 00:00:00 2001
From: "Thierry bordaz (tbordaz)" <tbordaz@redhat.com>
Date: Mon, 1 Sep 2014 11:30:05 +0200
Subject: [PATCH 1/2] Ticket 47828: DNA scope: allow to exlude some subtrees

Bug Description:
	DNA plugin generates attributes values to any added entry
	in the scope of the plugin (and filter).
	For ULC (http://www.freeipa.org/page/V3/User_Life-Cycle_Management),
	the provisioning container must be excluded.

Fix Description:
	Add the ability to define multivalued attribute: "dnaExcludeScope"
	in the config entry.
	DNA will not generate attributes values for entries added
	under one of the excluded DIT

http://fedorahosted.org/389/ticket/47828ticket URL>

Platforms tested: F17/F20

Flag Day: no

Doc impact: yes (adding a config attribute)
---
 ldap/schema/10dna-plugin.ldif  |  8 +++++
 ldap/servers/plugins/dna/dna.c | 73 +++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 80 insertions(+), 1 deletion(-)

diff --git a/ldap/schema/10dna-plugin.ldif b/ldap/schema/10dna-plugin.ldif
index 74f5f8b..3143904 100644
--- a/ldap/schema/10dna-plugin.ldif
+++ b/ldap/schema/10dna-plugin.ldif
@@ -202,6 +202,13 @@ attributeTypes: ( 2.16.840.1.113730.3.1.2160 NAME 'dnaRemoteBindMethod'
 #
 ################################################################################
 #
+attributeTypes: ( 2.16.840.1.113730.3.1.2312 NAME 'dnaExcludeScope'
+  DESC 'DN of a subtree excluded from DNA plugin scope'
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.12
+  X-ORIGIN '389 Directory Server' )
+#
+################################################################################
+#
 objectClasses: ( 2.16.840.1.113730.3.2.324 NAME 'dnaPluginConfig'
   DESC 'DNA plugin configuration'
   SUP top
@@ -214,6 +221,7 @@ objectClasses: ( 2.16.840.1.113730.3.2.324 NAME 'dnaPluginConfig'
         dnaMagicRegen $
         dnaFilter $
         dnaScope $
+        dnaExcludeScope $
         dnaSharedCfgDN $
         dnaThreshold $
         dnaNextRange $
diff --git a/ldap/servers/plugins/dna/dna.c b/ldap/servers/plugins/dna/dna.c
index 75edca8..b0887f1 100644
--- a/ldap/servers/plugins/dna/dna.c
+++ b/ldap/servers/plugins/dna/dna.c
@@ -87,6 +87,7 @@
 #define DNA_GENERATE        "dnaMagicRegen"
 #define DNA_FILTER          "dnaFilter"
 #define DNA_SCOPE           "dnaScope"
+#define DNA_EXCLUDE_SCOPE   "dnaExcludeScope"
 #define DNA_REMOTE_BIND_DN  "dnaRemoteBindDN"
 #define DNA_REMOTE_BIND_PW  "dnaRemoteBindCred"
 
@@ -164,6 +165,7 @@ struct configEntry {
     Slapi_Filter *slapi_filter;
     char *generate;
     char *scope;
+    Slapi_DN **excludescope;
     PRUint64 interval;
     PRUint64 threshold;
     char *shared_cfg_base;
@@ -355,6 +357,17 @@ dna_config_copy()
             new_entry->slapi_filter = slapi_filter_dup(config_entry->slapi_filter);
             new_entry->generate = slapi_ch_strdup(config_entry->generate);
             new_entry->scope = slapi_ch_strdup(config_entry->scope);
+            if (config_entry->excludescope == NULL) {
+                new_entry->excludescope = NULL;
+            } else {
+                int i;
+                
+                for (i = 0; config_entry->excludescope[i]; i++);
+                new_entry->excludescope = (Slapi_DN **) slapi_ch_calloc(sizeof (Slapi_DN *), i + 1);
+                for (i = 0; new_entry->excludescope[i]; i++) {
+                    new_entry->excludescope[i] = slapi_sdn_dup(config_entry->excludescope[i]);
+                }
+            }
             new_entry->shared_cfg_base = slapi_ch_strdup(config_entry->shared_cfg_base);
             new_entry->shared_cfg_dn   = slapi_ch_strdup(config_entry->shared_cfg_dn);
             new_entry->remote_binddn   = slapi_ch_strdup(config_entry->remote_binddn);
@@ -904,6 +917,7 @@ dna_parse_config_entry(Slapi_PBlock *pb, Slapi_Entry * e, int apply)
     int entry_added = 0;
     int i = 0;
     int ret = DNA_SUCCESS;
+    char **plugin_attr_values;
 
     slapi_log_error(SLAPI_LOG_TRACE, DNA_PLUGIN_SUBSYSTEM,
                     "--> dna_parse_config_entry\n");
@@ -1054,6 +1068,31 @@ dna_parse_config_entry(Slapi_PBlock *pb, Slapi_Entry * e, int apply)
 
     slapi_log_error(SLAPI_LOG_CONFIG, DNA_PLUGIN_SUBSYSTEM,
                     "----------> %s [%s]\n", DNA_SCOPE, entry->scope);
+    
+    plugin_attr_values = slapi_entry_attr_get_charray(e, DNA_EXCLUDE_SCOPE);
+    if (plugin_attr_values) {
+        int j = 0;
+        
+        /* Allocate the array of excluded scopes */
+        for (i = 0; plugin_attr_values[i]; i++);
+        entry->excludescope = (Slapi_DN **) slapi_ch_calloc(sizeof (Slapi_DN *), i + 1);
+        
+        /* Copy them in the config at the condition they are valid DN */
+        for (i = 0; plugin_attr_values[i]; i++) {
+            if (slapi_dn_syntax_check(NULL, plugin_attr_values[i], 1) == 1) {
+                slapi_log_error(SLAPI_LOG_FATAL, DNA_PLUGIN_SUBSYSTEM,
+                        "Error: Ignoring invalid DN used as excluded scope: [%s]\n",  plugin_attr_values[i]);
+                slapi_ch_free_string(&plugin_attr_values[i]);
+            } else {
+                entry->excludescope[j++] = slapi_sdn_new_dn_passin(plugin_attr_values[i]);
+            }
+        }
+        slapi_ch_free((void**) &plugin_attr_values);
+    }
+    for (i = 0; entry->excludescope && entry->excludescope[i]; i++) {
+        slapi_log_error(SLAPI_LOG_CONFIG, DNA_PLUGIN_SUBSYSTEM,
+                "----------> %s[%d] [%s]\n", DNA_EXCLUDE_SCOPE, i, slapi_sdn_get_dn(entry->excludescope[i]));
+    }
 
     /* optional, if not specified set -1 which is converted to the max unsigned
      * value */
@@ -1379,6 +1418,14 @@ dna_free_config_entry(struct configEntry ** entry)
     slapi_filter_free(e->slapi_filter, 1);
     slapi_ch_free_string(&e->generate);
     slapi_ch_free_string(&e->scope);
+    if (e->excludescope) {
+        int i;
+        
+        for (i = 0; e->excludescope[i]; i++) {
+            slapi_sdn_free(&e->excludescope[i]);
+        }
+        slapi_ch_free((void **)&e->excludescope);
+    }
     slapi_ch_free_string(&e->shared_cfg_base);
     slapi_ch_free_string(&e->shared_cfg_dn);
     slapi_ch_free_string(&e->remote_binddn);
@@ -3309,6 +3356,13 @@ _dna_pre_op_add(Slapi_PBlock *pb, Slapi_Entry *e, char **errstr)
                 goto next;
             }
 
+            /* is this entry in an excluded scope? */
+            for (i = 0; config_entry->excludescope && config_entry->excludescope[i]; i++) {
+                if (slapi_dn_issuffix(dn, slapi_sdn_get_dn(config_entry->excludescope[i]))) {
+                    goto next;
+                }
+            }
+            
             /* does the entry match the filter? */
             if (config_entry->slapi_filter) {
                 ret = slapi_vattr_filter_test(pb, e, config_entry->slapi_filter, 0);
@@ -3507,7 +3561,14 @@ _dna_pre_op_modify(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Mods *smods, char **e
                 !slapi_dn_issuffix(dn, config_entry->scope)) {
                 goto next;
             }
-
+            
+            /* is this entry in an excluded scope? */
+            for (i = 0; config_entry->excludescope && config_entry->excludescope[i]; i++) {
+                if (slapi_dn_issuffix(dn, slapi_sdn_get_dn(config_entry->excludescope[i]))) {
+                    goto next;
+                }
+            }
+            
             /* does the entry match the filter? */
             if (config_entry->slapi_filter) {
                 ret = slapi_vattr_filter_test(pb, e, 
@@ -3953,6 +4014,13 @@ static int dna_be_txn_pre_op(Slapi_PBlock *pb, int modtype)
                     goto next;
             }
 
+            /* is this entry in an excluded scope? */
+            for (i = 0; config_entry->excludescope && config_entry->excludescope[i]; i++) {
+                if (slapi_dn_issuffix(dn, slapi_sdn_get_dn(config_entry->excludescope[i]))) {
+                    goto next;
+                }
+            }
+            
             /* does the entry match the filter? */
             if (config_entry->slapi_filter) {
                 if(LDAP_SUCCESS != slapi_vattr_filter_test(pb,e,config_entry->slapi_filter, 0))
@@ -4560,6 +4628,9 @@ void dna_dump_config_entry(struct configEntry * entry)
     printf("<---- filter ---------> %s\n", entry->filter);
     printf("<---- prefix ---------> %s\n", entry->prefix);
     printf("<---- scope ----------> %s\n", entry->scope);
+    for (i = 0; entry->excludescope && entry->excludescope[i]; i++) {
+        printf("<---- excluded scope -> %s\n", slapi_sdn_get_dn(entry->excludescope[i]));
+    }
     printf("<---- next value -----> %" PRIu64 "\n", entry->nextval);
     printf("<---- max value ------> %" PRIu64 "\n", entry->maxval);
     printf("<---- interval -------> %" PRIu64 "\n", entry->interval);
-- 
1.7.11.7

