You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by sm...@apache.org on 2019/04/16 22:19:54 UTC

[directory-fortress-core] branch FC-267 created (now b680946)

This is an automated email from the ASF dual-hosted git repository.

smckinney pushed a change to branch FC-267
in repository https://gitbox.apache.org/repos/asf/directory-fortress-core.git.


      at b680946  FC-267 - New Configuration entity, interim

This branch includes the following new commits:

     new b680946  FC-267 - New Configuration entity, interim

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



[directory-fortress-core] 01/01: FC-267 - New Configuration entity, interim

Posted by sm...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

smckinney pushed a commit to branch FC-267
in repository https://gitbox.apache.org/repos/asf/directory-fortress-core.git

commit b6809466a061e3154d8e58d7d16142367ed1f4e0
Author: Shawn McKinney <sm...@apache.org>
AuthorDate: Tue Apr 16 17:19:49 2019 -0500

    FC-267 - New Configuration entity, interim
---
 build-config.xml                                   |   1 +
 .../fortress/core/ant/FortressAntTask.java         |  82 +++++---
 .../directory/fortress/core/impl/AdminMgrImpl.java |   3 +-
 .../directory/fortress/core/impl/ConfigDAO.java    | 107 +++++++----
 .../fortress/core/impl/ConfigMgrImpl.java          |  26 ++-
 .../directory/fortress/core/impl/ConfigP.java      |  27 +--
 .../directory/fortress/core/impl/UserDAO.java      |   4 +-
 .../fortress/core/model/Configuration.java         | 213 +++++++++++++++++++++
 .../fortress/core/rest/ConfigMgrRestImpl.java      |  21 ++
 .../directory/fortress/core/util/Config.java       |  35 +++-
 10 files changed, 427 insertions(+), 92 deletions(-)

diff --git a/build-config.xml b/build-config.xml
index 14a2399..eac2f6d 100644
--- a/build-config.xml
+++ b/build-config.xml
@@ -328,6 +328,7 @@
          <replace file="${dst.bootstrap.conf}" token="@TRUST_STORE@" value="${trust.store}"/>
          <replace file="${dst.bootstrap.conf}" token="@TRUST_STORE_PW@" value="${trust.store.password}"/>
          <replace file="${dst.bootstrap.conf}" token="@TRUST_STORE_ONCLASSPATHW@" value="${trust.store.onclasspath}"/>
+         <replace file="${dst.bootstrap.conf}" token="@IS_RFC2307@" value="${rfc2307}"/>
 
        <copy file="${src.remote.conf}" tofile="${dst.remote.conf}"/>
          <!-- These params are bound for config/config.properties file and contain coordinate to the target ldap server (only). -->
diff --git a/src/main/java/org/apache/directory/fortress/core/ant/FortressAntTask.java b/src/main/java/org/apache/directory/fortress/core/ant/FortressAntTask.java
index 2b3459c..6abe1a5 100755
--- a/src/main/java/org/apache/directory/fortress/core/ant/FortressAntTask.java
+++ b/src/main/java/org/apache/directory/fortress/core/ant/FortressAntTask.java
@@ -44,23 +44,8 @@ import org.apache.directory.fortress.core.PwPolicyMgrFactory;
 import org.apache.directory.fortress.core.SecurityException;
 import org.apache.directory.fortress.core.impl.OrganizationalUnitP;
 import org.apache.directory.fortress.core.impl.SuffixP;
-import org.apache.directory.fortress.core.model.AdminRole;
-import org.apache.directory.fortress.core.model.Context;
-import org.apache.directory.fortress.core.model.Group;
-import org.apache.directory.fortress.core.model.OrgUnit;
-import org.apache.directory.fortress.core.model.OrganizationalUnit;
-import org.apache.directory.fortress.core.model.PermGrant;
-import org.apache.directory.fortress.core.model.PermObj;
-import org.apache.directory.fortress.core.model.Permission;
+import org.apache.directory.fortress.core.model.*;
 import org.apache.directory.fortress.core.util.PropUtil;
-import org.apache.directory.fortress.core.model.PwPolicy;
-import org.apache.directory.fortress.core.model.Relationship;
-import org.apache.directory.fortress.core.model.Role;
-import org.apache.directory.fortress.core.model.SDSet;
-import org.apache.directory.fortress.core.model.Suffix;
-import org.apache.directory.fortress.core.model.User;
-import org.apache.directory.fortress.core.model.UserAdminRole;
-import org.apache.directory.fortress.core.model.UserRole;
 import org.apache.directory.fortress.core.util.ClassUtil;
 import org.apache.directory.fortress.core.util.Config;
 import org.apache.directory.fortress.core.util.Testable;
@@ -2527,13 +2512,14 @@ public class FortressAntTask extends Task implements InputHandler
      */
     private void addConfig() throws BuildException
     {
+        LOG.info( "addConfig" );
         if( addconfig == null )
         {
             return;
         }
 
         Properties props = new Properties();
-        String configNodeName = "";
+        Configuration configuration = new Configuration();
         // Loop through the entityclass elements
         for ( Addconfig addcfg : addconfig )
         {
@@ -2542,19 +2528,38 @@ public class FortressAntTask extends Task implements InputHandler
                 List<ConfigAnt> cfgs = addcfg.getConfig();
                 for ( ConfigAnt cfg : cfgs )
                 {
-                    LOG.info( "addConfig" );
                     String val = cfg.getProps();
                     int indx = val.indexOf( GlobalIds.PROP_SEP );
                     if ( indx >= 1 )
                     {
                         String name = val.substring( 0, indx );
                         String value = val.substring( indx + 1 );
-                        props.setProperty( name, value );
+
+                        // The config realm property is required on updconfig op and points to the existing node in ldap to update with these new props.
+                        if( name.equalsIgnoreCase( GlobalIds.CONFIG_REALM ))
+                        {
+                            configuration.setName( value );
+                        }
+                        else if( name.equalsIgnoreCase( GlobalIds.CONFIG_UID_NUMBER ))
+                        {
+                            configuration.setUidNumber( value );
+                        }
+                        else if( name.equalsIgnoreCase( GlobalIds.CONFIG_GID_NUMBER ))
+                        {
+                            configuration.setGidNumber( value );
+                        }
+                        else
+                        {
+                            props.setProperty( name, value );
+                            LOG.info( "addConfig name [{}] value [{}]", name, value );
+                        }
                     }
                 }
-                configNodeName = props.getProperty( GlobalIds.CONFIG_REALM );
-                LOG.info( "addConfig realm name [{}]", configNodeName );
-                cfgMgr.add( configNodeName, props );
+                configuration.addProperties( props );
+                LOG.info( "addConfig realm name [{}]", configuration.getName() );
+                LOG.info( "addConfig gid.number [{}]", configuration.getGidNumber() );
+                LOG.info( "addConfig uid.number [{}]", configuration.getUidNumber() );
+                cfgMgr.add( configuration );
             }
             catch ( SecurityException se )
             {
@@ -2562,18 +2567,18 @@ public class FortressAntTask extends Task implements InputHandler
                 {
                     try
                     {
-                        LOG.info( "addConfig realm name={} entry already exists, attempt to update", configNodeName );
-                        cfgMgr.update( configNodeName, props );
-                        LOG.info( "addConfig realm name={} update [{}] successful", configNodeName, configNodeName );
+                        LOG.info( "addConfig realm name={} entry already exists, attempt to update", configuration.getName() );
+                        cfgMgr.update( configuration );
+                        LOG.info( "addConfig realm name={} update [{}] successful", configuration.getName(), configuration.getName() );
                     }
                     catch ( SecurityException se2 )
                     {
-                        LOG.warn( "addConfig realm name={] update failed SecurityException={}", configNodeName, se2 );
+                        LOG.warn( "addConfig realm name={] update failed SecurityException={}", configuration.getName(), se2 );
                     }
                 }
                 else
                 {
-                    LOG.warn( "addConfig realm name={} failed SecurityException={}", configNodeName, se );
+                    LOG.warn( "addConfig realm name={} failed SecurityException={}", configuration.getName(), se );
                 }
             }
         }
@@ -2585,12 +2590,15 @@ public class FortressAntTask extends Task implements InputHandler
      */
     private void updConfig() throws BuildException
     {
+        LOG.info( "updateConfig" );
+
         if( updconfig == null )
         {
             return;
         }
 
         Properties props = new Properties();
+        Configuration configuration = new Configuration();
         String configNodeName = "";
         // Loop through the entityclass elements
         for ( Updconfig updcfg : updconfig )
@@ -2609,26 +2617,38 @@ public class FortressAntTask extends Task implements InputHandler
                     // The config realm property is required on updconfig op and points to the existing node in ldap to update with these new props.
                     if( name.equalsIgnoreCase( GlobalIds.CONFIG_REALM ))
                     {
-                        configNodeName = value;
+                        configuration.setName( value );
+                    }
+                    else if( name.equalsIgnoreCase( GlobalIds.CONFIG_UID_NUMBER ))
+                    {
+                        configuration.setUidNumber( value );
+                    }
+                    else if( name.equalsIgnoreCase( GlobalIds.CONFIG_GID_NUMBER ))
+                    {
+                        configuration.setGidNumber( value );
                     }
                     else
                     {
                         props.setProperty( name, value );
+                        LOG.info( "updateConfig name [{}] value [{}]", name, value );
                     }
                 }
             }
             // Can't go on w/out a name for the config node to update.
-            if ( StringUtils.isEmpty( configNodeName ))
+            if ( StringUtils.isEmpty( configuration.getName() ))
             {
                 LOG.warn( "updConfig realm name not specified, operation aborted." );
                 LOG.warn( "Add entry like this  to input xml: <config props=\"config.realm:DEFAULT\"/>" );
             }
             else
             {
+                configuration.addProperties( props );
+                LOG.info( "updConfig realm name [{}]", configuration.getName() );
+                LOG.info( "updConfig gid.number [{}]", configuration.getGidNumber() );
+                LOG.info( "updConfig uid.number [{}]", configuration.getUidNumber() );
                 try
                 {
-                    LOG.info( "updateConfig realm name [{}]", configNodeName );
-                    cfgMgr.update( configNodeName, props );
+                    cfgMgr.update( configuration );
                 }
                 catch ( SecurityException se )
                 {
diff --git a/src/main/java/org/apache/directory/fortress/core/impl/AdminMgrImpl.java b/src/main/java/org/apache/directory/fortress/core/impl/AdminMgrImpl.java
index 485f155..b2a820e 100755
--- a/src/main/java/org/apache/directory/fortress/core/impl/AdminMgrImpl.java
+++ b/src/main/java/org/apache/directory/fortress/core/impl/AdminMgrImpl.java
@@ -418,7 +418,8 @@ public final class AdminMgrImpl extends Manageable implements AdminMgr, Serializ
         props.setProperty( propKey, propValue );
         // Retrieve parameters from the config node stored in target LDAP DIT:
         String realmName = Config.getInstance().getProperty( GlobalIds.CONFIG_REALM, "DEFAULT" );
-        configP.update( realmName, props );
+
+        configP.update( new Configuration(realmName, props) );
         // update in-memory:
         Config.getInstance().setProperty( propKey, propValue );
     }
diff --git a/src/main/java/org/apache/directory/fortress/core/impl/ConfigDAO.java b/src/main/java/org/apache/directory/fortress/core/impl/ConfigDAO.java
index 6edaf5f..73f44ac 100755
--- a/src/main/java/org/apache/directory/fortress/core/impl/ConfigDAO.java
+++ b/src/main/java/org/apache/directory/fortress/core/impl/ConfigDAO.java
@@ -24,12 +24,10 @@ import java.util.ArrayList;
 import java.util.List;
 import java.util.Properties;
 
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.logging.Log;
 import org.apache.directory.api.ldap.model.constants.SchemaConstants;
-import org.apache.directory.api.ldap.model.entry.DefaultEntry;
-import org.apache.directory.api.ldap.model.entry.DefaultModification;
-import org.apache.directory.api.ldap.model.entry.Entry;
-import org.apache.directory.api.ldap.model.entry.Modification;
-import org.apache.directory.api.ldap.model.entry.ModificationOperation;
+import org.apache.directory.api.ldap.model.entry.*;
 import org.apache.directory.api.ldap.model.exception.LdapEntryAlreadyExistsException;
 import org.apache.directory.api.ldap.model.exception.LdapException;
 import org.apache.directory.api.ldap.model.exception.LdapNoSuchObjectException;
@@ -40,12 +38,16 @@ import org.apache.directory.fortress.core.GlobalIds;
 import org.apache.directory.fortress.core.RemoveException;
 import org.apache.directory.fortress.core.UpdateException;
 import org.apache.directory.fortress.core.ldap.LdapDataProvider;
+import org.apache.directory.fortress.core.model.Configuration;
 import org.apache.directory.fortress.core.util.PropUtil;
 import org.apache.directory.fortress.core.util.Config;
 import org.apache.directory.ldap.client.api.LdapConnection;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import static org.apache.directory.fortress.core.GlobalIds.GID_NUMBER;
+import static org.apache.directory.fortress.core.GlobalIds.UID_NUMBER;
+
 
 /**
  * This class provides data access for the standard ldap object device that has been extended to support name/value pairs.
@@ -82,22 +84,21 @@ import org.slf4j.LoggerFactory;
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  */
 final class ConfigDAO extends LdapDataProvider
-
 {
     private static final String CLS_NM = ConfigDAO.class.getName();
     private static final Logger LOG = LoggerFactory.getLogger( CLS_NM );
     private String CONFIG_ROOT_DN;
 
-    private final String CONFIG_OBJ_CLASS[] =
-        {
-            SchemaConstants.DEVICE_OC, GlobalIds.PROPS_AUX_OBJECT_CLASS_NAME
+    private final String[] CONFIG_OBJ_CLASS =
+    {
+        SchemaConstants.DEVICE_OC, GlobalIds.PROPS_AUX_OBJECT_CLASS_NAME, GlobalIds.FT_RFC2307_AUX_OBJECT_CLASS_NAME
     };
 
     private final String[] CONFIG_ATRS =
-        {
-            SchemaConstants.CN_AT, GlobalIds.PROPS
-    };
+    {
+        SchemaConstants.CN_AT, GlobalIds.PROPS, GID_NUMBER, UID_NUMBER
 
+    };
 
     /**
      * Package private default constructor.
@@ -108,28 +109,44 @@ final class ConfigDAO extends LdapDataProvider
     	CONFIG_ROOT_DN = Config.getInstance().getProperty( GlobalIds.CONFIG_ROOT_PARAM );
     }
 
-
     /**
      * Create a new configuration node and load it with properties.
-     * @param name of the new configuration node to be created in ldap.
-     * @param props each name/value pair becomes an ftprop in this entry.
-     * @return
+     * @param cfg the new configuration node to be created in ldap.
+     * @return what was just added.
      * @throws org.apache.directory.fortress.core.CreateException
      */
-    Properties create( String name, Properties props )
+    Configuration create( Configuration cfg )
         throws CreateException
     {
         LdapConnection ld = null;
-        String dn = getDn( name );
+        String dn = getDn( cfg.getName() );
         LOG.info( "create dn [{}]", dn );
         try
         {
             Entry myEntry = new DefaultEntry( dn );
             myEntry.add( SchemaConstants.OBJECT_CLASS_AT, CONFIG_OBJ_CLASS );
             ld = getAdminConnection();
-            myEntry.add( SchemaConstants.CN_AT, name );
-            loadProperties( props, myEntry, GlobalIds.PROPS );
-            add( ld, myEntry );
+            myEntry.add( SchemaConstants.CN_AT, cfg.getName() );
+            loadProperties( cfg.getProperties(), myEntry, GlobalIds.PROPS );
+            // These attributes hold sequence numbers:
+            if (StringUtils.isNotEmpty(cfg.getUidNumber()))
+            {
+                myEntry.add( GlobalIds.UID_NUMBER, cfg.getUidNumber() );
+            }
+            else
+            {
+                myEntry.add( GlobalIds.UID_NUMBER, "0" );
+            }
+            if (StringUtils.isNotEmpty(cfg.getGidNumber()))
+            {
+                myEntry.add( GlobalIds.GID_NUMBER, cfg.getGidNumber() );
+            }
+            else
+            {
+                myEntry.add( GlobalIds.GID_NUMBER, "0" );
+            }
+
+            add( ld, myEntry, cfg );
         }
         catch ( LdapEntryAlreadyExistsException e )
         {
@@ -148,36 +165,43 @@ final class ConfigDAO extends LdapDataProvider
         {
             closeAdminConnection( ld );
         }
-        return props;
+        return cfg;
     }
 
 
     /**
      * Update existing node with new properties.
-     * @param name contains existing config node name
-     * @param props each property name value will loaded into an attribute (ftprops) under the config node.
-     * @return
+     * @param cfg contains the name and each property name value will loaded into an attribute (ftprops) under the config node.
+     * @return the updated entity.
      * @throws org.apache.directory.fortress.core.UpdateException
      */
-    Properties update( String name, Properties props )
+    Configuration update( Configuration cfg )
         throws UpdateException
     {
         LdapConnection ld = null;
-        String dn = getDn( name );
-        LOG.info( "update dn [{}]", dn );
+        String dn = getDn( cfg.getName() );
+        LOG.debug( "update dn [{}]", dn );
         try
         {
             List<Modification> mods = new ArrayList<>();
-            if ( PropUtil.isNotEmpty( props ) )
+            if ( PropUtil.isNotEmpty( cfg.getProperties() ) )
             {
-                loadProperties( props, mods, GlobalIds.PROPS, false );
+                loadProperties( cfg.getProperties(), mods, GlobalIds.PROPS, false );
+            }
+            if (StringUtils.isNotEmpty(cfg.getUidNumber()))
+            {
+                mods.add(new DefaultModification(ModificationOperation.REPLACE_ATTRIBUTE, GlobalIds.UID_NUMBER,
+                        cfg.getUidNumber()));
+            }
+            if (StringUtils.isNotEmpty(cfg.getGidNumber()))
+            {
+                mods.add(new DefaultModification(ModificationOperation.REPLACE_ATTRIBUTE, GlobalIds.GID_NUMBER,
+                        cfg.getGidNumber()));
             }
-            ld = getAdminConnection();
             if ( mods.size() > 0 )
             {
                 ld = getAdminConnection();
-                // TODO: change to use modify that leaves audit trail:
-                modify( ld, dn, mods );
+                modify( ld, dn, mods, cfg );
             }
         }
         catch ( LdapException e )
@@ -189,7 +213,7 @@ final class ConfigDAO extends LdapDataProvider
         {
             closeAdminConnection( ld );
         }
-        return props;
+        return cfg;
     }
 
 
@@ -203,7 +227,7 @@ final class ConfigDAO extends LdapDataProvider
      * @throws UpdateException in the event the attribute can't be replaced.
      * @throws FinderException in the event the config node and/or property key:value can't be located.
      */
-    void updateProperty( String name, String key, String value, String newValue ) throws UpdateException, FinderException
+    void updateProperty( String name, String key, String value, String newValue ) throws UpdateException
     {
         LdapConnection ld = null;
         String dn = getDn( name );
@@ -297,13 +321,13 @@ final class ConfigDAO extends LdapDataProvider
 
     /**
      * @param name
-     * @return
+     * @return the existing config node.
      * @throws org.apache.directory.fortress.core.FinderException
      */
-    Properties getConfig( String name )
+    Configuration getConfig( String name )
         throws FinderException
     {
-        Properties props = null;
+        Configuration configuration = new Configuration();
         LdapConnection ld = null;
         String dn = getDn( name );
         LOG.debug( "getConfig dn [{}]", dn );
@@ -311,7 +335,10 @@ final class ConfigDAO extends LdapDataProvider
         {
             ld = getAdminConnection();
             Entry findEntry = read( ld, dn, CONFIG_ATRS );
-            props = PropUtil.getProperties( getAttributes( findEntry, GlobalIds.PROPS ) );
+            configuration.setName( name );
+            configuration.addProperties( PropUtil.getProperties( getAttributes( findEntry, GlobalIds.PROPS ) ) );
+            configuration.setUidNumber( getAttribute( findEntry, GlobalIds.UID_NUMBER ) );
+            configuration.setGidNumber( getAttribute( findEntry, GlobalIds.GID_NUMBER ) );
         }
         catch ( LdapNoSuchObjectException e )
         {
@@ -327,7 +354,7 @@ final class ConfigDAO extends LdapDataProvider
         {
             closeAdminConnection( ld );
         }
-        return props;
+        return configuration;
     }
 
 
diff --git a/src/main/java/org/apache/directory/fortress/core/impl/ConfigMgrImpl.java b/src/main/java/org/apache/directory/fortress/core/impl/ConfigMgrImpl.java
index 42dd967..4ba8dfb 100755
--- a/src/main/java/org/apache/directory/fortress/core/impl/ConfigMgrImpl.java
+++ b/src/main/java/org/apache/directory/fortress/core/impl/ConfigMgrImpl.java
@@ -23,7 +23,10 @@ import java.io.Serializable;
 import java.util.Properties;
 
 import org.apache.directory.fortress.core.ConfigMgr;
+import org.apache.directory.fortress.core.GlobalErrIds;
 import org.apache.directory.fortress.core.SecurityException;
+import org.apache.directory.fortress.core.model.Configuration;
+import org.apache.directory.fortress.core.util.VUtil;
 
 
 /**
@@ -39,9 +42,10 @@ import org.apache.directory.fortress.core.SecurityException;
  *
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  */
-public class ConfigMgrImpl implements ConfigMgr, Serializable
+public class ConfigMgrImpl  extends Manageable implements ConfigMgr, Serializable
 {
     private ConfigP cfgP;
+    private static final String CLS_NM = ConfigMgrImpl.class.getName();
 
     public ConfigMgrImpl() {
     	cfgP = new ConfigP();
@@ -51,9 +55,14 @@ public class ConfigMgrImpl implements ConfigMgr, Serializable
      * {@inheritDoc}
      */
     @Override
-    public Properties add(String name, Properties inProps) throws SecurityException
+    public Configuration add(Configuration cfg) throws SecurityException
     {
-        return cfgP.add(name, inProps);
+        String methodName = "add";
+        setEntitySession( CLS_NM, methodName, cfg );
+        assertContext( CLS_NM, methodName, cfg, GlobalErrIds.FT_CONFIG_NULL );
+        VUtil.assertNotNull( cfg, GlobalErrIds.FT_CONFIG_NULL, CLS_NM + methodName );
+        VUtil.assertNotNull( cfg.getName(), GlobalErrIds.FT_CONFIG_NAME_NULL, CLS_NM + methodName );
+        return cfgP.add(cfg);
     }
 
 
@@ -61,9 +70,14 @@ public class ConfigMgrImpl implements ConfigMgr, Serializable
      * {@inheritDoc}
      */
     @Override
-    public Properties update(String name, Properties inProps) throws SecurityException
+    public Configuration update(Configuration cfg) throws SecurityException
     {
-        return cfgP.update(name, inProps);
+        String methodName = "update";
+        setEntitySession( CLS_NM, methodName, cfg );
+        assertContext( CLS_NM, methodName, cfg, GlobalErrIds.FT_CONFIG_NULL );
+        VUtil.assertNotNull( cfg, GlobalErrIds.FT_CONFIG_NULL, CLS_NM + methodName );
+        VUtil.assertNotNull( cfg.getName(), GlobalErrIds.FT_CONFIG_NAME_NULL, CLS_NM + methodName );
+        return cfgP.update(cfg);
     }
 
     /**
@@ -97,7 +111,7 @@ public class ConfigMgrImpl implements ConfigMgr, Serializable
      * {@inheritDoc}
      */
     @Override
-    public Properties read(String name) throws SecurityException
+    public Configuration read(String name) throws SecurityException
     {
         return cfgP.read(name);
     }
diff --git a/src/main/java/org/apache/directory/fortress/core/impl/ConfigP.java b/src/main/java/org/apache/directory/fortress/core/impl/ConfigP.java
index e566216..efdec90 100755
--- a/src/main/java/org/apache/directory/fortress/core/impl/ConfigP.java
+++ b/src/main/java/org/apache/directory/fortress/core/impl/ConfigP.java
@@ -27,6 +27,7 @@ import org.apache.directory.fortress.core.GlobalErrIds;
 import org.apache.directory.fortress.core.GlobalIds;
 import org.apache.directory.fortress.core.SecurityException;
 import org.apache.directory.fortress.core.ValidationException;
+import org.apache.directory.fortress.core.model.Configuration;
 import org.apache.directory.fortress.core.util.VUtil;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -70,12 +71,13 @@ final class ConfigP
      * @return {@link Properties} containing the collection of name/value pairs just added.
      * @throws SecurityException in the event entry already present or other system error.
      */
-    Properties add( String name, Properties inProps )
+    //Properties add( String name, Properties inProps )
+    Configuration add(Configuration cfg)
         throws SecurityException
     {
-        validate( name, inProps );
+        validate( cfg.getName(), cfg.getProperties(), false );
         ConfigDAO cfgDao = new ConfigDAO();
-        return cfgDao.create( name, inProps );
+        return cfgDao.create( cfg );
     }
 
 
@@ -88,12 +90,13 @@ final class ConfigP
      * @return {@link Properties} containing the collection of name/value pairs to be added to existing node.
      * @throws org.apache.directory.fortress.core.SecurityException in the event entry not present or other system error.
      */
-    Properties update( String name, Properties inProps )
+    //Properties update( String name, Properties inProps )
+    Configuration update(Configuration cfg)
         throws SecurityException
     {
-        validate( name, inProps );
+        validate( cfg.getName(), cfg.getProperties(), true );
         ConfigDAO cfgDao = new ConfigDAO();
-        return cfgDao.update( name, inProps );
+        return cfgDao.update( cfg );
     }
 
 
@@ -153,7 +156,7 @@ final class ConfigP
     void delete( String name, Properties inProps )
         throws SecurityException
     {
-        validate( name, inProps );
+        validate( name, inProps, false );
         ConfigDAO cfgDao = new ConfigDAO();
         cfgDao.remove( name, inProps );
     }
@@ -167,13 +170,13 @@ final class ConfigP
      * @return {@link Properties} containing the collection of name/value pairs just added. Maps to 'ftProps' attribute in 'ftProperties' object class.
      * @throws org.apache.directory.fortress.core.SecurityException in the event entry doesn't exist or other system error.
      */
-    Properties read( String name )
+    Configuration read( String name )
         throws SecurityException
     {
         Properties outProps;
         ConfigDAO cfgDao = new ConfigDAO();
-        outProps = cfgDao.getConfig( name );
-        return outProps;
+        return cfgDao.getConfig( name );
+        //return outProps;
     }
 
 
@@ -185,7 +188,7 @@ final class ConfigP
      * @param entity contains the name/value properties targeted for operation.
      * @throws org.apache.directory.fortress.core.ValidationException thrown in the event the validations fail.
      */
-    private void validate( String name, Properties entity )
+    private void validate( String name, Properties entity, boolean isUpdate )
         throws ValidationException
     {
         if ( StringUtils.isEmpty( name ) )
@@ -200,7 +203,7 @@ final class ConfigP
             LOG.warn( error );
             throw new ValidationException( GlobalErrIds.FT_CONFIG_NAME_INVLD, error );
         }
-        if ( entity == null || entity.size() == 0 )
+        if ( !isUpdate && ( entity == null || entity.size() == 0 ) )
         {
             String error = "validate name [" + name + "] config props null";
             LOG.warn( error );
diff --git a/src/main/java/org/apache/directory/fortress/core/impl/UserDAO.java b/src/main/java/org/apache/directory/fortress/core/impl/UserDAO.java
index ba7b513..ce73393 100755
--- a/src/main/java/org/apache/directory/fortress/core/impl/UserDAO.java
+++ b/src/main/java/org/apache/directory/fortress/core/impl/UserDAO.java
@@ -83,6 +83,8 @@ import org.apache.directory.ldap.client.api.LdapConnection;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import static org.apache.directory.fortress.core.impl.RoleDAO.IS_RFC2307;
+
 
 /**
  * Data access class for LDAP User entity.
@@ -195,7 +197,7 @@ final class UserDAO extends LdapDataProvider implements PropUpdater
     // RFC2307bis decls:
     private static final String POSIX_ACCOUNT = "posixAccount";
     private static final String HOME_DIRECTORY =  "homeDirectory";
-    private static final boolean IS_RFC2307 = Config.getInstance().getProperty( GlobalIds.RFC2307_PROP ) != null && Config.getInstance().getProperty( GlobalIds.RFC2307_PROP ).equalsIgnoreCase( "true" ) ? true : false;
+    //private static final boolean IS_RFC2307 = Config.getInstance().getProperty( GlobalIds.RFC2307_PROP ) != null && Config.getInstance().getProperty( GlobalIds.RFC2307_PROP ).equalsIgnoreCase( "true" ) ? true : false;
     /**
      * RF2307bis uses groupOfNames instead of ftRA:
      */
diff --git a/src/main/java/org/apache/directory/fortress/core/model/Configuration.java b/src/main/java/org/apache/directory/fortress/core/model/Configuration.java
new file mode 100644
index 0000000..a2d06e8
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/model/Configuration.java
@@ -0,0 +1,213 @@
+/*
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *   or more contributor license agreements.  See the NOTICE file
+ *   distributed with this work for additional information
+ *   regarding copyright ownership.  The ASF licenses this file
+ *   to you under the Apache License, Version 2.0 (the
+ *   "License"); you may not use this file except in compliance
+ *   with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing,
+ *   software distributed under the License is distributed on an
+ *   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *   KIND, either express or implied.  See the License for the
+ *   specific language governing permissions and limitations
+ *   under the License.
+ *
+ */
+package org.apache.directory.fortress.core.model;
+
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.Objects;
+import java.util.Properties;
+
+/**
+ * A class for passing configuration information.
+ */
+@XmlRootElement(name = "fortConfiguration")
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "configuration", propOrder =
+{
+        "name",
+        "props",
+        "uidNumber",
+        "gidNumber"
+})
+public class Configuration extends FortEntity
+{
+
+    public Configuration()
+    {
+    }
+
+    public Configuration(String name, Properties props)
+    {
+        this.name = name;
+        addProperties( props );
+    }
+
+    private String name;
+    private Props props = new Props();
+    private String uidNumber;
+    private String gidNumber;
+
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    /**
+     * Gets the value of the Props property.  This method is used by Fortress Core and Rest and should not be called by external programs.
+     *
+     * @return possible object is {@link Props }
+     *
+     */
+    public Props getProps()
+    {
+        return props;
+    }
+
+
+    /**
+     * Sets the value of the Props property.  This method is used by Fortress Core and Rest and should not be called by external programs.
+     *
+     * @param value allowed object is {@link Props }
+     *
+     */
+    public void setProps( Props value )
+    {
+        this.props = value;
+    }
+
+
+    /**
+     * Add name/value pair to list of properties associated with Configuration node.  These values are not constrained by Fortress.
+     * Properties are optional.
+     *
+     * @param key   contains property name and maps to 'ftProps' attribute in 'ftProperties' aux object class.
+     * @param value The property value to add
+     */
+    public void addProperty( String key, String value )
+    {
+        Props.Entry entry = new Props.Entry();
+        entry.setKey( key );
+        entry.setValue( value );
+        props.getEntry().add( entry );
+    }
+
+
+    /**
+     * Get a name/value pair attribute from list of properties associated with Configuration node.  These values are not constrained by Fortress.
+     * Properties are optional.
+     *
+     * @param key contains property name and maps to 'ftProps' attribute in 'ftProperties' aux object class.
+     * @return value containing name/value pair that maps to 'ftProps' attribute in 'ftProperties' aux object class.
+     */
+    public String getProperty( String key )
+    {
+        List<Props.Entry> props = this.props.getEntry();
+        Props.Entry keyObj = new Props.Entry();
+        keyObj.setKey( key );
+
+        String value = null;
+        int indx = props.indexOf( keyObj );
+
+        if ( indx != -1 )
+        {
+            Props.Entry entry = props.get( props.indexOf( keyObj ) );
+            value = entry.getValue();
+        }
+
+        return value;
+    }
+
+
+    /**
+     * Add new collection of name/value pairs to attributes associated with Configuration node.  These values are not constrained by Fortress.
+     * Properties are optional.
+     *
+     * @param props contains collection of name/value pairs and maps to 'ftProps' attribute in 'ftProperties' aux object class.
+     */
+    public void addProperties( Properties props )
+    {
+        if ( props != null )
+        {
+            for (Enumeration<?> e = props.propertyNames(); e.hasMoreElements(); )
+            {
+                // This LDAP attr is stored as a name-value pair separated by a ':'.
+                String key = ( String ) e.nextElement();
+                String val = props.getProperty( key );
+                addProperty( key, val );
+            }
+        }
+    }
+
+
+    /**
+     * Return the collection of name/value pairs to attributes associated with Configuration node.  These values are not constrained by Fortress.
+     * Properties are optional.
+     *
+     * @return Properties contains collection of name/value pairs and maps to 'ftProps' attribute in 'ftProperties' aux object class.
+     */
+    public Properties getProperties()
+    {
+        Properties properties = null;
+        List<Props.Entry> props = this.props.getEntry();
+
+        if ( props.size() > 0 )
+        {
+            properties = new Properties();
+
+            for ( Props.Entry entry : props )
+            {
+                String key = entry.getKey();
+                String val = entry.getValue();
+                properties.setProperty( key, val );
+            }
+        }
+
+        return properties;
+    }
+
+    public String getUidNumber() {
+        return uidNumber;
+    }
+
+    public void setUidNumber(String uidNumber) {
+        this.uidNumber = uidNumber;
+    }
+
+    public String getGidNumber() {
+        return gidNumber;
+    }
+
+    public void setGidNumber(String gidNumber) {
+        this.gidNumber = gidNumber;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        Configuration that = (Configuration) o;
+        return Objects.equals(name, that.name);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(name);
+    }
+}
+
diff --git a/src/main/java/org/apache/directory/fortress/core/rest/ConfigMgrRestImpl.java b/src/main/java/org/apache/directory/fortress/core/rest/ConfigMgrRestImpl.java
index 99011f4..5fe8930 100644
--- a/src/main/java/org/apache/directory/fortress/core/rest/ConfigMgrRestImpl.java
+++ b/src/main/java/org/apache/directory/fortress/core/rest/ConfigMgrRestImpl.java
@@ -24,6 +24,7 @@ import java.util.Properties;
 import org.apache.directory.fortress.core.ConfigMgr;
 import org.apache.directory.fortress.core.GlobalErrIds;
 import org.apache.directory.fortress.core.SecurityException;
+import org.apache.directory.fortress.core.model.Configuration;
 import org.apache.directory.fortress.core.model.FortRequest;
 import org.apache.directory.fortress.core.model.FortResponse;
 import org.apache.directory.fortress.core.model.Props;
@@ -50,6 +51,12 @@ public class ConfigMgrRestImpl implements ConfigMgr
      * {@inheritDoc}
      */
     @Override
+    public Configuration add(Configuration cfg) throws SecurityException
+    {
+        throw new UnsupportedOperationException( "not implemented" );
+    }
+/*
+    @Override
     public Properties add(String name, Properties inProperties) throws SecurityException
     {
         VUtil.assertNotNull(name, GlobalErrIds.FT_CONFIG_NAME_NULL, CLS_NM + ".add");
@@ -73,12 +80,19 @@ public class ConfigMgrRestImpl implements ConfigMgr
         }
         return retProperties;
     }
+*/
 
 
     /**
      * {@inheritDoc}
      */
     @Override
+    public Configuration update(Configuration cfg) throws SecurityException
+    {
+        throw new UnsupportedOperationException( "not implemented" );
+    }
+/*
+    @Override
     public Properties update(String name, Properties inProperties) throws SecurityException
     {
         VUtil.assertNotNull(name, GlobalErrIds.FT_CONFIG_NAME_NULL, CLS_NM + ".update");
@@ -102,6 +116,7 @@ public class ConfigMgrRestImpl implements ConfigMgr
         }
         return retProperties;
     }
+*/
 
 
     /**
@@ -159,6 +174,11 @@ public class ConfigMgrRestImpl implements ConfigMgr
      * {@inheritDoc}
      */
     @Override
+    public Configuration read(String name) throws SecurityException
+    {
+        throw new java.lang.UnsupportedOperationException();
+    }
+/*
     public Properties read(String name) throws SecurityException
     {
         VUtil.assertNotNull(name, GlobalErrIds.FT_CONFIG_NAME_NULL, CLS_NM + ".readRole");
@@ -180,4 +200,5 @@ public class ConfigMgrRestImpl implements ConfigMgr
         }
         return retProps;
     }
+*/
 }
\ No newline at end of file
diff --git a/src/main/java/org/apache/directory/fortress/core/util/Config.java b/src/main/java/org/apache/directory/fortress/core/util/Config.java
index cc70c70..08fd7dc 100755
--- a/src/main/java/org/apache/directory/fortress/core/util/Config.java
+++ b/src/main/java/org/apache/directory/fortress/core/util/Config.java
@@ -33,6 +33,7 @@ import org.apache.directory.fortress.core.ConfigMgrFactory;
 import org.apache.directory.fortress.core.GlobalErrIds;
 import org.apache.directory.fortress.core.GlobalIds;
 import org.apache.directory.fortress.core.SecurityException;
+import org.apache.directory.fortress.core.model.Configuration;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -139,6 +140,36 @@ public final class Config
         try
         {
             ConfigMgr cfgMgr = ConfigMgrFactory.createInstance();
+            org.apache.directory.fortress.core.model.Configuration inConfig = cfgMgr.read( name );
+            org.apache.directory.fortress.core.model.Configuration outConfig = new Configuration();
+            outConfig.setName( name );
+            if( key.equals( GlobalIds.UID_NUMBER ))
+            {
+                value = inConfig.getUidNumber();
+                outConfig.setUidNumber( propUpdater.newValue( value ) );
+            }
+            else
+            {
+                value = inConfig.getGidNumber();
+                outConfig.setGidNumber( propUpdater.newValue( inConfig.getGidNumber() ) );
+            }
+            cfgMgr.update( outConfig );
+        }
+        catch ( SecurityException se )
+        {
+            String error = "replaceProperty failed, exception=" + se.getMessage();
+            throw new CfgRuntimeException( GlobalErrIds.FT_CONFIG_UPDATE_FAILED, error, se );
+        }
+        return value;
+    }
+
+/*
+    public synchronized String replacePropertyx( String name, String key, PropUpdater propUpdater ) throws CfgException
+    {
+        String value;
+        try
+        {
+            ConfigMgr cfgMgr = ConfigMgrFactory.createInstance();
             Properties props = cfgMgr.read( name );
             // TODO: The key should be scoped to an instance, e.g. FORT104
             value = props.getProperty( key );
@@ -153,6 +184,7 @@ public final class Config
         }
         return value;
     }
+*/
 
     /**
      * Gets the prop attribute as String value from the apache commons cfg component.
@@ -410,7 +442,8 @@ public final class Config
         {
             String configClassName = this.getProperty( GlobalIds.CONFIG_IMPLEMENTATION );
             ConfigMgr cfgMgr = ConfigMgrFactory.createInstance(configClassName, false);
-            props = cfgMgr.read( realmName );
+            Configuration configuration = cfgMgr.read( realmName );
+            props = configuration.getProperties();
         }
         catch ( CfgException ce )
         {