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 2014/10/22 17:44:59 UTC

[40/51] [partial] Rename packages from org.openldap.fortress to org.apache.directory.fortress.core. Change default suffix to org.apache. Switch default ldap api from unbound to apache ldap.

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/ant/PermAnt.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/ant/PermAnt.java b/src/main/java/org/apache/directory/fortress/core/ant/PermAnt.java
new file mode 100755
index 0000000..c865deb
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/ant/PermAnt.java
@@ -0,0 +1,68 @@
+/*
+ *   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.ant;
+
+
+import org.apache.directory.fortress.core.rbac.Permission;
+
+import java.util.StringTokenizer;
+
+/**
+ * Entity is used by custom Apache Ant task for special handling of collections.  This is necessary because the
+ * Ant parser cannot deal with complex data attribute types.  The class extends a base entity.
+ *
+ * @author Shawn McKinney
+ */
+public class PermAnt extends Permission
+{
+    private String antRoles;
+
+    /**
+     * Return the roles as a String.
+     *
+     * @return String contains a comma delimited set of role names assigned to permission.
+     */
+    public String getAntRoles()
+    {
+        return antRoles;
+    }
+
+    /**
+     * Accept a comma delimited String containing a list of Roles to be granted to a permission.  This function
+     * will parse the String and call the setter on its parent.
+     *
+     * @param antRoles contains a comma delimited set of role names.
+     */
+    public void setAntRoles(String antRoles)
+    {
+        this.antRoles = antRoles;
+        // allow the setter to process comma delimited strings:
+        StringTokenizer tkn = new StringTokenizer(antRoles, ",");
+        if (tkn.countTokens() > 0)
+        {
+            while (tkn.hasMoreTokens())
+            {
+                String rTkn = tkn.nextToken();
+                setRole(rTkn);
+            }
+        }
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/ant/SDSetAnt.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/ant/SDSetAnt.java b/src/main/java/org/apache/directory/fortress/core/ant/SDSetAnt.java
new file mode 100755
index 0000000..c9dbda9
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/ant/SDSetAnt.java
@@ -0,0 +1,99 @@
+/*
+ *   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.ant;
+
+
+import org.apache.directory.fortress.core.rbac.SDSet;
+
+import java.util.StringTokenizer;
+
+/**
+ * Entity is used by custom Apache Ant task for special handling of collections.  This is necessary because the
+ * Ant parser cannot deal with complex data attribute types.  The class extends a base entity.
+ *
+ * @author Shawn McKinney
+ */
+public class SDSetAnt extends SDSet
+{
+    private String type;
+    private String members;
+
+    /**
+     * Return the members as a String.
+     *
+     * @return String contain comma delimited list of members.
+     */
+    public String getSetMembers()
+    {
+        return members;
+    }
+
+    /**
+     * Accept a comma delimited list of members, iterate of each and call the setter on the parent class.
+     *
+     * @param members contains comma delimited set of members.
+     */
+    public void setSetMembers(String members)
+    {
+        this.members = members;
+        if (members != null)
+        {
+            StringTokenizer tkn = new StringTokenizer(members, ",");
+            if (tkn.countTokens() > 0)
+            {
+                while (tkn.hasMoreTokens())
+                {
+                    String member = tkn.nextToken();
+                    addMember(member);
+                }
+            }
+        }
+    }
+
+
+    /**
+     * Return the type of SD set in string format.
+     *
+     * @return String that represents static or dynamic relations.
+     */
+    public String getSetType()
+    {
+        return type;
+    }
+
+    /**
+     * Method accepts a String variable that maps to its parent's set type.
+     *
+     * @param type String value represents static or dynamic set relations.
+     */
+    public void setSetType(String type)
+    {
+        this.type = type;
+        if (type != null && type.equals("DYNAMIC"))
+        {
+            setType(SDSet.SDType.DYNAMIC);
+        }
+        else
+        {
+            setType(SDSet.SDType.STATIC);
+        }
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/ant/UserAnt.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/ant/UserAnt.java b/src/main/java/org/apache/directory/fortress/core/ant/UserAnt.java
new file mode 100755
index 0000000..b75775a
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/ant/UserAnt.java
@@ -0,0 +1,301 @@
+/*
+ *   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.ant;
+
+
+import org.apache.commons.io.FileUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.apache.directory.fortress.core.rbac.User;
+import org.apache.directory.fortress.core.util.attr.AttrHelper;
+import org.apache.directory.fortress.core.util.attr.VUtil;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.util.StringTokenizer;
+
+/**
+ * Entity is used by custom Apache Ant task for special handling of collections.  This is necessary because the
+ * Ant parser cannot deal with complex data attribute types.  The class extends a base entity.
+ *
+ * @author Shawn McKinney
+ */
+public class UserAnt extends User
+{
+    private String userProps;
+    private String email;
+    private String phone;
+    private String mobile;
+    private String city;
+    private String state;
+    private String addresses;
+    private String postalCode;
+    private String postOfficeBox;
+    private String building;
+    private String departmentNumber;
+    private String roomNumber;
+    private String photo;
+    private static final String CLS_NM = UserAnt.class.getName();
+    private static final Logger LOG = LoggerFactory.getLogger( CLS_NM );
+
+    public String getAddresses()
+    {
+        return addresses;
+    }
+
+    public void setAddresses(String addresses)
+    {
+        this.addresses = addresses;
+         // allow the setter to process comma delimited strings:
+         StringTokenizer tkn = new StringTokenizer(addresses, ",");
+         if (tkn.countTokens() > 0)
+         {
+             while (tkn.hasMoreTokens())
+             {
+                 String aTkn = tkn.nextToken();
+                 getAddress().setAddress(aTkn);
+             }
+         }
+    }
+
+    public String getUserProps()
+    {
+        return userProps;
+    }
+
+    public void setUserProps( String userProps )
+    {
+        this.userProps = userProps;
+        addProperties(AttrHelper.getProperties(userProps));
+    }
+
+    public String getPostalCode()
+    {
+        return postalCode;
+    }
+
+    public void setPostalCode(String postalCode)
+    {
+        getAddress().setPostalCode(postalCode);
+    }
+
+    public String getPostOfficeBox()
+    {
+        return postOfficeBox;
+    }
+
+    public void setPostOfficeBox(String postOfficeBox)
+    {
+        getAddress().setPostOfficeBox(postOfficeBox);
+    }
+
+    public String getBuilding()
+    {
+        return building;
+    }
+
+    public void setBuilding(String building)
+    {
+        getAddress().setBuilding(building);
+    }
+
+    public String getDepartmentNumber()
+    {
+        return departmentNumber;
+    }
+
+    public void setDepartmentNumber(String departmentNumber)
+    {
+        getAddress().setDepartmentNumber(departmentNumber);
+    }
+
+    public String getRoomNumber()
+    {
+        return roomNumber;
+    }
+
+    public void setRoomNumber(String roomNumber)
+    {
+        getAddress().setRoomNumber(roomNumber);
+    }
+
+    public String getCity()
+    {
+        return city;
+    }
+
+    public void setCity(String city)
+    {
+        getAddress().setCity(city);
+    }
+
+    public String getState()
+    {
+        return state;
+    }
+
+    public void setState(String state)
+    {
+        getAddress().setState(state);
+    }
+
+    public String getCountry()
+    {
+        return country;
+    }
+
+    public void setCountry(String country)
+    {
+        getAddress().setCountry(country);
+    }
+
+    private String country;
+
+
+    /**
+     * Generally not good practice to handle passwords as Strings in Java but this method allows Ant's digester to consume field in String format from the xml input file.
+     * It subsequently converts to char[] as needed by the parent entity - {@link User}.
+     *
+     * @param password String format will be converted to char[].
+     */
+    public void setPassword(String password)
+    {
+        super.setPassword(password.toCharArray());
+    }
+
+    public String getPhone()
+    {
+        return phone;
+    }
+
+    public void setPhone(String phone)
+    {
+        this.phone = phone;
+        // allow the setter to process comma delimited strings:
+        StringTokenizer tkn = new StringTokenizer(phone, ",");
+        if (tkn.countTokens() > 0)
+        {
+            while (tkn.hasMoreTokens())
+            {
+                String pTkn = tkn.nextToken();
+                getPhones().add(pTkn);
+            }
+        }
+    }
+
+    public String getEmail()
+    {
+        return email;
+    }
+
+    public void setEmail(String email)
+    {
+        this.email = email;
+        // allow the setter to process comma delimited strings:
+        StringTokenizer tkn = new StringTokenizer(email, ",");
+        if (tkn.countTokens() > 0)
+        {
+            while (tkn.hasMoreTokens())
+            {
+                String eTkn = tkn.nextToken();
+                getEmails().add(eTkn);
+            }
+        }
+    }
+
+    public String getMobile()
+    {
+        return mobile;
+    }
+
+    public void setMobile(String mobile)
+    {
+        this.mobile = mobile;
+        // allow the setter to process comma delimited strings:
+        StringTokenizer tkn = new StringTokenizer(mobile, ",");
+        if (tkn.countTokens() > 0)
+        {
+            while (tkn.hasMoreTokens())
+            {
+                String pTkn = tkn.nextToken();
+                getMobiles().add(pTkn);
+            }
+        }
+    }
+
+    public String getPhoto()
+    {
+        return photo;
+    }
+
+    public void setPhoto( String photo )
+    {
+        this.photo = photo;
+        if( VUtil.isNotNullOrEmpty( photo ))
+        {
+            byte[] jpeg = getJpegPhoto( photo );
+            if( VUtil.isNotNullOrEmpty( jpeg ))
+            {
+                setJpegPhoto( jpeg );
+            }
+        }
+    }
+
+    private static byte[] getJpegPhoto( String fileName )
+    {
+        byte[] value = null;
+        try
+        {
+            value = readJpegFile( fileName );
+        }
+        catch ( ArrayIndexOutOfBoundsException ae )
+        {
+            // attribute is optional, do nothing here
+        }
+
+        return value;
+    }
+
+    public static byte[] readJpegFile( String fileName )
+    {
+        URL fUrl = UserAnt.class.getClassLoader().getResource( fileName );
+        byte[] image = null;
+        try
+        {
+            if ( fUrl != null )
+            {
+                image = FileUtils.readFileToByteArray( new File( fUrl.toURI() ) );
+            }
+        }
+        catch ( URISyntaxException se )
+        {
+            String warn = "readJpegFile caught URISyntaxException=" + se;
+            LOG.warn( warn );
+        }
+        catch ( IOException ioe )
+        {
+            String warn = "readJpegFile caught IOException=" + ioe;
+            LOG.warn( warn );
+        }
+        return image;
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/ant/package.html
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/ant/package.html b/src/main/java/org/apache/directory/fortress/core/ant/package.html
new file mode 100755
index 0000000..ab32115
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/ant/package.html
@@ -0,0 +1,35 @@
+<!--
+ *   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.
+ *
+-->
+<html>
+   <head>
+      <title>Package Documentation for org.apache.directory.fortress.core.ant</title>
+   </head>
+   <body>
+      <p>
+         This package use <a href="http://ant.apache.org/">Apache Ant</a> to provide utility to provision fortress entities and policies
+         using XML files.
+      </p>
+      <p>
+         The <A HREF="package-summary.html">org.apache.directory.fortress.core.ant</a> package provides a provisioning utility that uses
+         xml files that use Apache Ant to drive fortress administrative APIs.
+         See the {@link org.apache.directory.fortress.core.ant.FortressAntTask FortressAntTask} java doc for more info on how it works.
+      </p>
+   </body>
+</html>

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/cfg/Config.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/cfg/Config.java b/src/main/java/org/apache/directory/fortress/core/cfg/Config.java
new file mode 100755
index 0000000..782c28e
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/cfg/Config.java
@@ -0,0 +1,347 @@
+/*
+ *   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.cfg;
+
+
+import java.net.URL;
+import java.util.Enumeration;
+import java.util.Properties;
+
+import org.apache.commons.configuration.PropertiesConfiguration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.apache.directory.fortress.core.CfgException;
+import org.apache.directory.fortress.core.CfgRuntimeException;
+import org.apache.directory.fortress.core.GlobalErrIds;
+import org.apache.directory.fortress.core.GlobalIds;
+import org.apache.directory.fortress.core.SecurityException;
+
+
+/**
+ * This class wraps <a href="http://commons.apache.org/cfg/">Apache Commons Config</a> utility and is used by internal components to retrieve name-value
+ * pair properties from its cfg context.  The class will combine properties that it finds in its local property
+ * file along with data that is retrieved by name from the ldap server if name is specified within
+ * the {@link org.apache.directory.fortress.core.GlobalIds#CONFIG_REALM} switch.
+ * <p>
+ * The class will bootstrap itself during startup and must initialize correctly for the Fortress APIs to work correctly.
+ * <p>
+ * This object is thread safe but stores a static reference to Apache Commons Configuration {@link #config} object.
+ * </p>
+ *
+ * @author Shawn McKinney
+ */
+public class Config
+{
+    final private static String propFile = "fortress.properties";
+    final private static String userPropFile = "fortress.user.properties";
+    private static final PropertiesConfiguration config;
+    private static final String CLS_NM = Config.class.getName();
+    final private static Logger LOG = LoggerFactory.getLogger( CLS_NM );
+
+    static
+    {
+        try
+        {
+            // Load the system config bootstrap xml file.
+            URL fUrl = Config.class.getClassLoader().getResource( propFile );
+
+            if ( fUrl == null )
+            {
+                String error = "static init: Error, null cfg file: " + propFile;
+                LOG.error( error );
+                throw new java.lang.RuntimeException( error );
+            }
+
+            LOG.info( "static init: found from: {} path: {}", propFile, fUrl.getPath() );
+
+            config = new PropertiesConfiguration();
+            config.setDelimiterParsingDisabled( true );
+            config.load( fUrl );
+            LOG.info( "static init: loading from: {}", propFile );
+
+            URL fUserUrl = Config.class.getClassLoader().getResource( userPropFile );
+            if ( fUserUrl != null )
+            {
+                LOG.info( "static init: found user properties from: {} path: {}",
+                    userPropFile, fUserUrl.getPath() );
+                config.load( fUserUrl );
+            }
+
+            String realmName = config.getString( GlobalIds.CONFIG_REALM );
+            if ( realmName != null && realmName.length() > 0 )
+            {
+                LOG.info( "static init: load config realm [{}]", realmName );
+                Properties props = getRemoteConfig( realmName );
+                if ( props != null )
+                {
+                    for ( Enumeration e = props.propertyNames(); e.hasMoreElements(); )
+                    {
+                        String key = ( String ) e.nextElement();
+                        String val = props.getProperty( key );
+                        config.addProperty( key, val );
+                    }
+                }
+            }
+            else
+            {
+                LOG.info( "static init: config realm not setup" );
+            }
+        }
+        catch ( org.apache.commons.configuration.ConfigurationException ex )
+        {
+            String error = "static init: Error loading from cfg file: [" + propFile
+                + "] ConfigurationException=" + ex;
+            LOG.error( error );
+            throw new CfgRuntimeException( GlobalErrIds.FT_CONFIG_BOOTSTRAP_FAILED, error, ex );
+        }
+        catch ( SecurityException se )
+        {
+            String error = "static init: Error loading from cfg file: [" + propFile + "] SecurityException="
+                + se;
+            LOG.error( error );
+            throw new CfgRuntimeException( GlobalErrIds.FT_CONFIG_INITIALIZE_FAILED, error, se );
+        }
+    }
+
+
+    /**
+     * Fetch the remote cfg params from ldap with given name.
+     *
+     * @param realmName required attribute contains the name of config node name on ldap.
+     * @return {@link Properties} containing collection of name/value pairs found in directory.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          in the event of system or validation error.
+     */
+    private static Properties getRemoteConfig( String realmName ) throws SecurityException
+    {
+        Properties props = null;
+        try
+        {
+            ConfigMgr cfgMgr = ConfigMgrFactory.createInstance();
+            props = cfgMgr.read( realmName );
+        }
+        catch ( CfgException ce )
+        {
+            if ( ce.getErrorId() == GlobalErrIds.FT_CONFIG_NOT_FOUND )
+            {
+                String warning = "getRemoteConfig could not find cfg entry";
+                LOG.warn( warning );
+            }
+            else
+            {
+                throw ce;
+            }
+        }
+        return props;
+    }
+
+
+    /**
+     * Gets the prop attribute as String value from the apache commons cfg component.
+     *
+     * @param name contains the name of the property.
+     * @return contains the value associated with the property or null if not not found.
+     */
+    public static String getProperty( String name )
+    {
+        String value = null;
+        if ( config != null )
+        {
+            value = ( String ) config.getProperty( name );
+            if ( LOG.isDebugEnabled() )
+                LOG.debug( "getProperty name [{}] value [{}]", name, value );
+        }
+        else
+        {
+            String error = "getProperty invalid config, can't read prop [" + name + "]";
+            LOG.error( error );
+        }
+        return value;
+    }
+
+
+    /**
+     * Get the property value from the apache commons config but specify a default value if not found.
+     *
+     * @param name         contains the name of the property.
+     * @param defaultValue specified by client will be returned if property value is not found.
+     * @return contains the value for the property as a String.
+     */
+    public static String getProperty( String name, String defaultValue )
+    {
+        String value = null;
+        if ( config != null )
+        {
+            value = ( String ) config.getProperty( name );
+        }
+        else
+        {
+            String warn = "getProperty invalid config, can't read prop [" + name + "]";
+            LOG.warn( warn );
+        }
+        if ( value == null || value.length() == 0 )
+        {
+            value = defaultValue;
+        }
+        return value;
+    }
+
+
+    /**
+     * Gets the prop attribute as char value from the apache commons cfg component.
+     *
+     * @param name contains the name of the property.
+     * @return contains the value associated with the property or 0 if not not found.
+     */
+    public static char getChar( String name )
+    {
+        char value = 0;
+        if ( config != null )
+        {
+            value = ( char ) config.getProperty( name );
+            if ( LOG.isDebugEnabled() )
+                LOG.debug( "getChar name [{}] value [{}]", name, value );
+        }
+        else
+        {
+            String error = "getChar invalid config, can't read prop [" + name + "]";
+            LOG.error( error );
+        }
+        return value;
+    }
+
+
+    /**
+     * Get the property value from the apache commons config but specify a default value if not found.
+     *
+     * @param name         contains the name of the property.
+     * @param defaultValue specified by client will be returned if property value is not found.
+     * @return contains the value for the property as a char.
+     */
+    public static char getChar( String name, char defaultValue )
+    {
+        char value = 0;
+        if ( config != null )
+        {
+            value = ( char ) config.getProperty( name );
+        }
+        else
+        {
+            String warn = "getChar invalid config, can't read prop [" + name + "]";
+            LOG.warn( warn );
+        }
+        if ( value == 0 )
+        {
+            value = defaultValue;
+        }
+        return value;
+    }
+
+
+    /**
+     * Gets the int attribute of the Config class, or 0 if not found.
+     *
+     * @param key name of the property name.
+     * @return The int value or 0 if not found.
+     */
+    public static int getInt( String key )
+    {
+        int value = 0;
+        if ( config != null )
+        {
+            value = config.getInt( key );
+        }
+        else
+        {
+            String warn = "getInt invalid config, can't read prop [" + key + "]";
+            LOG.warn( warn );
+        }
+        return value;
+    }
+
+
+    /**
+     * Gets the int attribute of the Config class or default value if not found.
+     *
+     * @param key          name of the property name.
+     * @param defaultValue to use if property not found.
+     * @return The int value or default value if not found.
+     */
+    public static int getInt( String key, int defaultValue )
+    {
+        int value = 0;
+        if ( config != null )
+        {
+            value = config.getInt( key, defaultValue );
+        }
+        else
+        {
+            String warn = "getInt invalid config, can't read prop [" + key + "]";
+            LOG.warn( warn );
+        }
+        return value;
+    }
+
+
+    /**
+     * Gets the boolean attribute associated with the name or false if not found.
+     *
+     * @param key name of the property name.
+     * @return The boolean value or false if not found.
+     */
+    public static boolean getBoolean( String key )
+    {
+        boolean value = false;
+        if ( config != null )
+        {
+            value = config.getBoolean( key );
+        }
+        else
+        {
+            String warn = "getBoolean - invalid config, can't read prop [" + key + "]";
+            LOG.warn( warn );
+        }
+        return value;
+    }
+
+
+    /**
+     * Gets the boolean attribute associated with the name or false if not found.
+     *
+     * @param key          name of the property name.
+     * @param defaultValue specified by client will be returned if property value is not found.
+     * @return The boolean value or false if not found.
+     */
+    public static boolean getBoolean( String key, boolean defaultValue )
+    {
+        boolean value = defaultValue;
+        if ( config != null )
+        {
+            value = config.getBoolean( key, defaultValue );
+        }
+        else
+        {
+            String warn = "getBoolean - invalid config, can't read prop [" + key + "]";
+            LOG.warn( warn );
+        }
+        return value;
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/cfg/ConfigDAO.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/cfg/ConfigDAO.java b/src/main/java/org/apache/directory/fortress/core/cfg/ConfigDAO.java
new file mode 100755
index 0000000..1d8f07a
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/cfg/ConfigDAO.java
@@ -0,0 +1,299 @@
+/*
+ *   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.cfg;
+
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Properties;
+
+import org.apache.directory.api.ldap.model.entry.DefaultEntry;
+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.exception.LdapEntryAlreadyExistsException;
+import org.apache.directory.api.ldap.model.exception.LdapException;
+import org.apache.directory.api.ldap.model.exception.LdapNoSuchObjectException;
+import org.apache.directory.fortress.core.CreateException;
+import org.apache.directory.ldap.client.api.LdapConnection;
+import org.apache.directory.fortress.core.ldap.ApacheDsDataProvider;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.apache.directory.fortress.core.FinderException;
+import org.apache.directory.fortress.core.GlobalErrIds;
+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.util.attr.AttrHelper;
+import org.apache.directory.fortress.core.util.attr.VUtil;
+
+/**
+ * This class provides data access for the standard ldap object device that has been extended to support name/value pairs.
+ * Fortress uses this data structure to store its remote cfg parameters.
+ * <p/>
+ * The Fortress Config node is a combination of:
+ * <p/>
+ * 'device' Structural Object Class is used to store basic attributes like cn which will be used for config node name.
+ * <ul>
+ * <li>  ------------------------------------------
+ * <li> <code>objectclass ( 2.5.6.14 NAME 'device'</code>
+ * <li> <code>DESC 'RFC2256: a device''</code>
+ * <li> <code>SUP top STRUCTURAL</code>
+ * <li> <code>MUST cn</code>
+ * <li> <code>MAY ( serialNumber $ seeAlso $ owner $ ou $ o $ l $ description ) )</code>
+ * <li>  ------------------------------------------
+ * </ul>
+ * <p/>
+ * 'ftProperties' AUXILIARY Object Class is used to store name/value pairs on target node.<br />
+ * <code>This aux object class can be used to store custom attributes.</code><br />
+ * <code>The properties collections consist of name/value pairs and are not constrainted by Fortress.</code><br />
+ * <ul>
+ * <li>  ------------------------------------------
+ * <li> <code>objectclass ( 1.3.6.1.4.1.38088.3.2</code>
+ * <li> <code>NAME 'ftProperties'</code>
+ * <li> <code>DESC 'Fortress Properties AUX Object Class'</code>
+ * <li> <code>AUXILIARY</code>
+ * <li> <code>MAY ( ftProps ) ) </code>
+ * <li>  ------------------------------------------
+ * </ul>
+ * <p/>
+ * <p/>
+ * This class is thread safe.
+ *
+ * @author Shawn McKinney
+ */
+final class ConfigDAO extends ApacheDsDataProvider
+
+{
+    private static final String CLS_NM = ConfigDAO.class.getName();
+    private static final Logger LOG = LoggerFactory.getLogger( CLS_NM );
+    private static final String CONFIG_ROOT_PARAM = "config.root";
+    private static final String CONFIG_ROOT_DN = Config.getProperty( CONFIG_ROOT_PARAM );
+    private static final String DEVICE_OBJECT_CLASS_NM = "device";
+
+    private static final String CONFIG_OBJ_CLASS[] =
+        {
+            DEVICE_OBJECT_CLASS_NM, GlobalIds.PROPS_AUX_OBJECT_CLASS_NAME
+    };
+
+    private static final String[] CONFIG_ATRS =
+        {
+            GlobalIds.CN, GlobalIds.PROPS
+    };
+
+    /**
+     * Package private default constructor.
+     */
+    ConfigDAO()
+    {
+    }
+
+    /**
+     * @param name
+     * @param props
+     * @return
+     * @throws org.apache.directory.fortress.core.CreateException
+     */
+    final Properties create( String name, Properties props )
+        throws CreateException
+    {
+        LdapConnection ld = null;
+        String dn = getDn( name );
+        LOG.info( "create dn [" + dn + "]" );
+        try
+        {
+            Entry myEntry = new DefaultEntry( dn );
+            myEntry.add( GlobalIds.OBJECT_CLASS, CONFIG_OBJ_CLASS );
+            ld = getAdminConnection();
+            myEntry.add( GlobalIds.CN, name );
+            loadProperties( props, myEntry, GlobalIds.PROPS );
+            add( ld, myEntry );
+        }
+        catch ( LdapEntryAlreadyExistsException e )
+        {
+            String warning = "create config dn [" + dn + "] caught LdapEntryAlreadyExistsException="
+                + e.getMessage() + " msg=" + e.getMessage();
+            throw new CreateException( GlobalErrIds.FT_CONFIG_ALREADY_EXISTS, warning );
+        }
+        catch ( LdapException e )
+        {
+            String error;
+            error = "create config dn [" + dn + "] caught LDAPException=" + e.getMessage();
+            LOG.error( error, e );
+            throw new CreateException( GlobalErrIds.FT_CONFIG_CREATE_FAILED, error );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+        return props;
+    }
+
+
+    /**
+     * @param name
+     * @param props
+     * @return
+     * @throws org.apache.directory.fortress.core.UpdateException
+     */
+    final Properties update( String name, Properties props )
+        throws UpdateException
+    {
+        LdapConnection ld = null;
+        String dn = getDn( name );
+        LOG.info( "update dn [" + dn + "]" );
+        try
+        {
+            List<Modification> mods = new ArrayList<Modification>();
+            if ( VUtil.isNotNullOrEmpty( props ) )
+            {
+                loadProperties( props, mods, GlobalIds.PROPS, true );
+            }
+            ld = getAdminConnection();
+            if ( mods.size() > 0 )
+            {
+                ld = getAdminConnection();
+                modify( ld, dn, mods );
+            }
+        }
+        catch ( LdapException e )
+        {
+            String error = "update dn [" + dn + "] caught LDAPException=" + e.getMessage();
+            throw new UpdateException( GlobalErrIds.FT_CONFIG_UPDATE_FAILED, error );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+        return props;
+    }
+
+
+    /**
+     * @param name
+     * @throws org.apache.directory.fortress.core.RemoveException
+     */
+    final void remove( String name )
+        throws RemoveException
+    {
+        LdapConnection ld = null;
+        String dn = getDn( name );
+        LOG.info( "remove dn [" + dn + "]" );
+        try
+        {
+            ld = getAdminConnection();
+            delete( ld, dn );
+        }
+        catch ( LdapException e )
+        {
+            String error = "remove dn [" + dn + "] LDAPException=" + e.getMessage();
+            throw new RemoveException( GlobalErrIds.FT_CONFIG_DELETE_FAILED, error );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+    }
+
+
+    /**
+     * @param name
+     * @param props
+     * @return
+     * @throws org.apache.directory.fortress.core.UpdateException
+     */
+    final Properties remove( String name, Properties props )
+        throws UpdateException
+    {
+        LdapConnection ld = null;
+        String dn = getDn( name );
+        LOG.info( "remove props dn [" + dn + "]" );
+        try
+        {
+            List<Modification> mods = new ArrayList<Modification>();
+            if ( VUtil.isNotNullOrEmpty( props ) )
+            {
+                removeProperties( props, mods, GlobalIds.PROPS );
+            }
+            if ( mods.size() > 0 )
+            {
+                ld = getAdminConnection();
+                modify( ld, dn, mods );
+            }
+        }
+        catch ( LdapException e )
+        {
+            String error = "remove props dn [" + dn + "] caught LDAPException=" + e.getMessage();
+            throw new UpdateException( GlobalErrIds.FT_CONFIG_DELETE_PROPS_FAILED, error );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+        return props;
+    }
+
+
+    /**
+     * @param name
+     * @return
+     * @throws org.apache.directory.fortress.core.FinderException
+     */
+    final Properties getConfig( String name )
+        throws FinderException
+    {
+        Properties props = null;
+        LdapConnection ld = null;
+        String dn = getDn( name );
+        LOG.info( "getConfig dn [" + dn + "]" );
+        try
+        {
+            ld = getAdminConnection();
+            Entry findEntry = read( ld, dn, CONFIG_ATRS );
+            props = AttrHelper.getProperties( getAttributes( findEntry, GlobalIds.PROPS ) );
+        }
+        catch ( LdapNoSuchObjectException e )
+        {
+            String warning = "getConfig COULD NOT FIND ENTRY for dn [" + dn + "]";
+            throw new FinderException( GlobalErrIds.USER_NOT_FOUND, warning );
+        }
+        catch ( LdapException e )
+        {
+            String error = "getConfig dn [" + dn + "] caught LdapException=" + e.getMessage();
+            throw new FinderException( GlobalErrIds.FT_CONFIG_READ_FAILED, error );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+        return props;
+    }
+
+
+    /**
+     *
+     * @param name
+     * @return
+     */
+    private String getDn( String name )
+    {
+        return GlobalIds.CN + "=" + name + "," + CONFIG_ROOT_DN;
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/cfg/ConfigMgr.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/cfg/ConfigMgr.java b/src/main/java/org/apache/directory/fortress/core/cfg/ConfigMgr.java
new file mode 100755
index 0000000..e0e15c9
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/cfg/ConfigMgr.java
@@ -0,0 +1,96 @@
+/*
+ *   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.cfg;
+
+import org.apache.directory.fortress.core.SecurityException;
+
+import java.util.Properties;
+
+/**
+ * This interface prescribes CRUD methods used to manage properties stored within the ldap directory.
+ * The Fortress config nodes are used to remotely share Fortress client specific properties between processes.
+ * Fortress places no limits on the number of unique configurations that can be present at one time in the directory.
+ * The Fortress client will specify the preferred cfg node by name via a property named, {@link org.apache.directory.fortress.core.GlobalIds#CONFIG_REALM}.
+ * Each process using Fortress client is free to share an existing node with other processes or create its own unique config
+ * instance using the methods within this class.<BR>
+ * <p/>
+ * This class is thread safe.
+ * <p/>
+
+ *
+ * @author Shawn McKinney
+ */
+public interface ConfigMgr
+{
+    /**
+     * Create a new cfg node with given name and properties.  The name is required.  If node already exists,
+     * a {@link org.apache.directory.fortress.core.SecurityException} with error {@link org.apache.directory.fortress.core.GlobalErrIds#FT_CONFIG_ALREADY_EXISTS} will be thrown.
+     *
+     * @param name    attribute is required and maps to 'cn' attribute in 'device' object class.
+     * @param inProps contains {@link Properties} with list of name/value pairs to add to existing config node.
+     * @return {@link Properties} containing the collection of name/value pairs just added.
+     * @throws org.apache.directory.fortress.core.SecurityException in the event entry already present or other system error.
+     */
+    public Properties add(String name, Properties inProps) throws SecurityException;
+
+    /**
+     * Update existing cfg node with additional properties, or, replace existing properties.  The name is required.  If node does not exist,
+     * a {@link org.apache.directory.fortress.core.SecurityException} with error {@link org.apache.directory.fortress.core.GlobalErrIds#FT_CONFIG_NOT_FOUND} will be thrown.
+     *
+     * @param name    attribute is required and maps to 'cn' attribute in 'device' object class.
+     * @param inProps contains {@link Properties} with list of name/value pairs to add or udpate from existing config node.
+     * @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.
+     */
+    public Properties update(String name, Properties inProps) throws SecurityException;
+
+    /**
+     * Completely removes named cfg node from the directory.
+     * <p/>
+     * <font size="3" color="red">This method is destructive and will remove the cfg node completely from directory.<BR>
+     * Care should be taken during execution to ensure target name is correct and permanent removal of all parameters located
+     * there is intended.  There is no 'undo' for this operation.
+     * </font>
+     *
+     * @param name is required and maps to 'cn' attribute on 'device' object class of node targeted for operation.
+     * @throws org.apache.directory.fortress.core.SecurityException in the event of system error.
+     */
+    public void delete(String name) throws SecurityException;
+
+    /**
+     * Delete properties from existing cfg node.  The name is required.  If node does not exist,
+     * a {@link org.apache.directory.fortress.core.SecurityException} with error {@link org.apache.directory.fortress.core.GlobalErrIds#FT_CONFIG_NOT_FOUND} will be thrown.
+     *
+     * @param name attribute is required and maps to 'cn' attribute in 'device' object class.
+     * @throws org.apache.directory.fortress.core.SecurityException in the event entry not present or other system error.
+     */
+    public void delete(String name, Properties inProps) throws SecurityException;
+
+    /**
+     * Read an existing cfg node with given name and return to caller.  The name is required.  If node doesn't exist,
+     * a {@link org.apache.directory.fortress.core.SecurityException} with error {@link org.apache.directory.fortress.core.GlobalErrIds#FT_CONFIG_NOT_FOUND} will be thrown.
+     *
+     * @param name attribute is required and maps to 'cn' attribute in 'device' object class.
+     * @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.
+     */
+    public Properties read(String name) throws SecurityException;
+}
+

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/cfg/ConfigMgrFactory.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/cfg/ConfigMgrFactory.java b/src/main/java/org/apache/directory/fortress/core/cfg/ConfigMgrFactory.java
new file mode 100755
index 0000000..8211769
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/cfg/ConfigMgrFactory.java
@@ -0,0 +1,68 @@
+/*
+ *   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.cfg;
+
+import org.apache.directory.fortress.core.GlobalIds;
+import org.apache.directory.fortress.core.rbac.ClassUtil;
+import org.apache.directory.fortress.core.SecurityException;
+import org.apache.directory.fortress.core.rest.ConfigMgrRestImpl;
+
+/**
+ * Creates an instance of the ConfigMgr object.
+ * <p/>
+ * The default implementation class is specified as {@link ConfigMgrImpl} but can be overridden by
+ * adding the {@link org.apache.directory.fortress.core.GlobalIds#CONFIG_IMPLEMENTATION} config property.
+ * <p/>
+
+ *
+ * @author Shawn McKinney
+ */
+public class ConfigMgrFactory
+{
+    private static String configClassName = Config.getProperty(GlobalIds.CONFIG_IMPLEMENTATION);
+    private final static String ENABLE_REST = "enable.mgr.impl.rest";
+    private static final boolean IS_REST = ((Config.getProperty(ENABLE_REST) != null) && (Config.getProperty(ENABLE_REST).equalsIgnoreCase("true")));
+
+    /**
+     * Create and return a reference to {@link ConfigMgr} object.
+     *
+     * @return instance of {@link ConfigMgr}.
+     * @throws org.apache.directory.fortress.core.SecurityException in the event of failure during instantiation.
+     */
+    public static ConfigMgr createInstance()
+        throws SecurityException
+    {
+        // TODO: Don't reuse {@link VUtil#isNotNullOrEmpty} here until it is determined why it forces different execution path through GlobalIds.IS_OPENLDAP:
+        //if (!VUtil.isNotNullOrEmpty(configClassName))
+        if (configClassName == null || configClassName.compareTo("") == 0)
+        {
+            if(IS_REST)
+            {
+                configClassName = ConfigMgrRestImpl.class.getName();
+            }
+            else
+            {
+                configClassName = ConfigMgrImpl.class.getName();
+            }
+        }
+
+        return (ConfigMgr) ClassUtil.createInstance(configClassName);
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/cfg/ConfigMgrImpl.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/cfg/ConfigMgrImpl.java b/src/main/java/org/apache/directory/fortress/core/cfg/ConfigMgrImpl.java
new file mode 100755
index 0000000..1358f7e
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/cfg/ConfigMgrImpl.java
@@ -0,0 +1,119 @@
+/*
+ *   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.cfg;
+
+import org.apache.directory.fortress.core.SecurityException;
+
+import java.util.Properties;
+
+
+/**
+ * This Manager impl supplies CRUD methods used to manage properties stored within the ldap directory.
+ * The Fortress config nodes are used to remotely share Fortress client specific properties between processes.
+ * Fortress places no limits on the number of unique configurations that can be present at one time in the directory.
+ * The Fortress client will specify the preferred cfg node by name via a property named, {@link org.apache.directory.fortress.core.GlobalIds#CONFIG_REALM}.
+ * Each process using Fortress client is free to share an existing node with other processes or create its own unique config
+ * instance using the methods within this class.<BR>
+ * <p/>
+ * This class is thread safe.
+ * <p/>
+
+ *
+ * @author Shawn McKinney
+ */
+public class ConfigMgrImpl implements ConfigMgr
+{
+    private static final ConfigP cfgP = new ConfigP();
+
+    /**
+     * Create a new cfg node with given name and properties.  The name is required.  If node already exists,
+     * a {@link org.apache.directory.fortress.core.SecurityException} with error {@link org.apache.directory.fortress.core.GlobalErrIds#FT_CONFIG_ALREADY_EXISTS} will be thrown.
+     *
+     * @param name    attribute is required and maps to 'cn' attribute in 'device' object class.
+     * @param inProps contains {@link Properties} with list of name/value pairs to add to existing config node.
+     * @return {@link Properties} containing the collection of name/value pairs just added.
+     * @throws org.apache.directory.fortress.core.SecurityException in the event entry already present or other system error.
+     */
+    @Override
+    public Properties add(String name, Properties inProps) throws SecurityException
+    {
+        return cfgP.add(name, inProps);
+    }
+
+
+    /**
+     * Update existing cfg node with additional properties, or, replace existing properties.  The name is required.  If node does not exist,
+     * a {@link org.apache.directory.fortress.core.SecurityException} with error {@link org.apache.directory.fortress.core.GlobalErrIds#FT_CONFIG_NOT_FOUND} will be thrown.
+     *
+     * @param name    attribute is required and maps to 'cn' attribute in 'device' object class.
+     * @param inProps contains {@link Properties} with list of name/value pairs to add or udpate from existing config node.
+     * @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.
+     */
+    @Override
+    public Properties update(String name, Properties inProps) throws SecurityException
+    {
+        return cfgP.update(name, inProps);
+    }
+
+    /**
+     * Completely removes named cfg node from the directory.
+     * <p/>
+     * <font size="3" color="red">This method is destructive and will remove the cfg node completely from directory.<BR>
+     * Care should be taken during execution to ensure target name is correct and permanent removal of all parameters located
+     * there is intended.  There is no 'undo' for this operation.
+     * </font>
+     *
+     * @param name is required and maps to 'cn' attribute on 'device' object class of node targeted for operation.
+     * @throws org.apache.directory.fortress.core.SecurityException in the event of system error.
+     */
+    @Override
+    public void delete(String name) throws SecurityException
+    {
+        cfgP.delete(name);
+    }
+
+    /**
+     * Delete properties from existing cfg node.  The name is required.  If node does not exist,
+     * a {@link org.apache.directory.fortress.core.SecurityException} with error {@link org.apache.directory.fortress.core.GlobalErrIds#FT_CONFIG_NOT_FOUND} will be thrown.
+     *
+     * @param name attribute is required and maps to 'cn' attribute in 'device' object class.
+     * @throws org.apache.directory.fortress.core.SecurityException in the event entry not present or other system error.
+     */
+    @Override
+    public void delete(String name, Properties inProps) throws SecurityException
+    {
+        cfgP.delete(name, inProps);
+    }
+
+    /**
+     * Read an existing cfg node with given name and return to caller.  The name is required.  If node doesn't exist,
+     * a {@link org.apache.directory.fortress.core.SecurityException} with error {@link org.apache.directory.fortress.core.GlobalErrIds#FT_CONFIG_NOT_FOUND} will be thrown.
+     *
+     * @param name attribute is required and maps to 'cn' attribute in 'device' object class.
+     * @return {@link Properties} containing the collection of name/value pairs just added. Maps to 'ftProps' attribute in 'ftProperties' object class.
+     * @throws SecurityException in the event entry doesn't exist or other system error.
+     */
+    @Override
+    public Properties read(String name) throws SecurityException
+    {
+        return cfgP.read(name);
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/cfg/ConfigP.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/cfg/ConfigP.java b/src/main/java/org/apache/directory/fortress/core/cfg/ConfigP.java
new file mode 100755
index 0000000..ad8b1d2
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/cfg/ConfigP.java
@@ -0,0 +1,202 @@
+/*
+ *   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.cfg;
+
+
+import java.util.Properties;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+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.util.attr.VUtil;
+
+
+/**
+ * Process module for the configurations node used for remotely storing Fortress specific properties.
+ * Fortress places no limits on the number of unique configurations that can be present.  The Fortress client will specify
+ * the preferred cfg node by name via a property named, {@link org.apache.directory.fortress.core.GlobalIds#CONFIG_REALM}.  Each
+ * process using Fortress client is free to share existing node with other processes or create its own unique config
+ * instance using the methods within this class.<BR>
+ * This class does perform simple data validations to ensure data reasonability and the required fields are present.<BR>
+ * The {@link org.apache.directory.fortress.core.ant.FortressAntTask#addConfig()} method calls the {@link #add} from this class during initial base loads.
+ * Removal {@link org.apache.directory.fortress.core.ant.FortressAntTask#deleteConfig()} is performed when removal of properties is the aim.<BR>
+ * This class will accept {@link Properties}, and forward on to it's corresponding DAO class {@link ConfigDAO} for updating properties stored on behalf of Fortress.
+ * <p>
+ * Class will throw {@link SecurityException} to caller in the event of security policy, data constraint violation or system
+ * error internal to DAO object. This class will forward DAO exceptions ({@link org.apache.directory.fortress.core.FinderException},
+ * {@link org.apache.directory.fortress.core.CreateException},{@link org.apache.directory.fortress.core.UpdateException},{@link org.apache.directory.fortress.core.RemoveException}),
+ *  or {@link org.apache.directory.fortress.core.ValidationException} as {@link org.apache.directory.fortress.core.SecurityException}s with appropriate
+ *  error id from {@link org.apache.directory.fortress.core.GlobalErrIds}.
+ * <p>
+ * This class performs simple data validation on properties to ensure length does not exceed 100 and contents are safe text.
+ * <p/>
+
+ *
+ * @author Shawn McKinney
+ */
+final class ConfigP
+{
+    private static final String CLS_NM = ConfigP.class.getName();
+    private static final Logger LOG = LoggerFactory.getLogger( CLS_NM );
+
+
+    /**
+     * Package private constructor
+     */
+    ConfigP()
+    {
+    }
+
+
+    /**
+     * Create a new cfg node with given name and properties.  The name is required.  If node already exists,
+     * a {@link org.apache.directory.fortress.core.SecurityException} with error {@link GlobalErrIds#FT_CONFIG_ALREADY_EXISTS} will be thrown.
+     *
+     * @param name    attribute is required and maps to 'cn' attribute in 'device' object class.
+     * @param inProps contains {@link Properties} with list of name/value pairs to remove from existing config node.
+     * @return {@link Properties} containing the collection of name/value pairs just added.
+     * @throws SecurityException in the event entry already present or other system error.
+     */
+    final Properties add( String name, Properties inProps )
+        throws SecurityException
+    {
+        validate( name, inProps );
+        ConfigDAO cfgDao = new ConfigDAO();
+        return cfgDao.create( name, inProps );
+    }
+
+
+    /**
+     * Update existing cfg node with additional properties, or, replace existing properties.  The name is required.  If node does not exist,
+     * a {@link SecurityException} with error {@link org.apache.directory.fortress.core.GlobalErrIds#FT_CONFIG_NOT_FOUND} will be thrown.
+     *
+     * @param name    attribute is required and maps to 'cn' attribute in 'device' object class.
+     * @param inProps contains {@link Properties} with list of name/value pairs to add or udpate from existing config node.
+     * @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.
+     */
+    final Properties update( String name, Properties inProps )
+        throws SecurityException
+    {
+        validate( name, inProps );
+        ConfigDAO cfgDao = new ConfigDAO();
+        return cfgDao.update( name, inProps );
+    }
+
+
+    /**
+     * Delete existing cfg node which will remove all properties associated with that node.
+     * The name is required.  If node does not exist, a {@link SecurityException} with error
+     * {@link GlobalErrIds#FT_CONFIG_NOT_FOUND} will be thrown.
+     * <p/>
+     * <font size="2" color="red">
+     * This method is destructive and will remove the cfg node completely from directory.<BR>
+     * Care should be taken during execution to ensure target name is correct and permanent removal of all parameters located
+     * there is intended.  There is no 'undo' for this operation.
+     * </font>
+     * <p/>
+     * @param name attribute is required and maps to 'cn' attribute in 'device' object class.
+     * @return {@link Properties} containing the collection of name/value pairs to be added to existing node.
+     * @throws SecurityException in the event entry not present or other system error.
+     */
+    final void delete( String name )
+        throws SecurityException
+    {
+        if ( !VUtil.isNotNullOrEmpty( name ) )
+        {
+            String error = "delete detected null config realm name";
+            LOG.warn( error );
+            throw new ValidationException( GlobalErrIds.FT_CONFIG_NAME_NULL, error );
+        }
+        ConfigDAO cfgDao = new ConfigDAO();
+        cfgDao.remove( name );
+    }
+
+
+    /**
+     * Delete existing cfg node with additional properties, or, replace existing properties.  The name is required.  If node does not exist,
+     * a {@link SecurityException} with error {@link org.apache.directory.fortress.core.GlobalErrIds#FT_CONFIG_NOT_FOUND} will be thrown.
+     *
+     * @param name attribute is required and maps to 'cn' attribute in 'device' object class.
+     * @throws org.apache.directory.fortress.core.SecurityException in the event entry not present or other system error.
+     */
+    final void delete( String name, Properties inProps )
+        throws SecurityException
+    {
+        validate( name, inProps );
+        ConfigDAO cfgDao = new ConfigDAO();
+        cfgDao.remove( name, inProps );
+    }
+
+
+    /**
+     * Read an existing cfg node with given name and return to caller.  The name is required.  If node doesn't exist,
+     * a {@link SecurityException} with error {@link org.apache.directory.fortress.core.GlobalErrIds#FT_CONFIG_NOT_FOUND} will be thrown.
+     *
+     * @param name attribute is required and maps to 'cn' attribute in 'device' object class.
+     * @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.
+     */
+    final Properties read( String name )
+        throws SecurityException
+    {
+        Properties outProps;
+        ConfigDAO cfgDao = new ConfigDAO();
+        outProps = cfgDao.getConfig( name );
+        return outProps;
+    }
+
+
+    /**
+     * Method will perform simple validations to ensure the integrity of the {@link Properties} entity targeted for insertion
+     * or deletion in directory.
+     *
+     * @param name contains the name of the cfg node.
+     * @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 )
+        throws ValidationException
+    {
+        if ( !VUtil.isNotNullOrEmpty( name ) )
+        {
+            String error = "validate detected null config realm name";
+            LOG.warn( error );
+            throw new ValidationException( GlobalErrIds.FT_CONFIG_NAME_NULL, error );
+        }
+        if ( name.length() > GlobalIds.OU_LEN )
+        {
+            String error = "validate name [" + name + "] invalid length [" + name.length() + "]";
+            LOG.warn( error );
+            throw new ValidationException( GlobalErrIds.FT_CONFIG_NAME_INVLD, error );
+        }
+        if ( entity == null || entity.size() == 0 )
+        {
+            String error = "validate name [" + name + "] config props null";
+            LOG.warn( error );
+            throw new ValidationException( GlobalErrIds.FT_CONFIG_PROPS_NULL, error );
+        }
+        VUtil.properties( entity );
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/cfg/package.html
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/cfg/package.html b/src/main/java/org/apache/directory/fortress/core/cfg/package.html
new file mode 100755
index 0000000..0bc922e
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/cfg/package.html
@@ -0,0 +1,37 @@
+<!--
+ *   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.
+ *
+-->
+<html>
+   <head>
+      <title>Package Documentation for org.apache.directory.fortress.config</title>
+   </head>
+   <body>
+      <p>
+         This package uses <a href="http://commons.apache.org/configuration/">Apache Commons Configuration</a> APIs to provide configuration data to fortress along with CRUD APIs for storing config data on the ldap server.
+      </p>
+      <p>
+         The <b>org.apache.directory.fortress.config</b> can store its data both in a flat file or within the LDAP directory itself.
+          The <b>oamConfig.xml</b> contains the location of the bootstrap property file.  The bootstrap properties
+          can then point to a remote LDAP configuration node, called a 'realm', and referenced with this property:
+          <b>config.realm</b>.  An empty or null value for the config.realm property means the properties will all be stored locally in the file specified within oamConfig.xml.
+          The package also contains entities and apis that are used to perform CRUD on remote configuration parameters.
+          See the corresponding javadoc contained with this package for more info.
+      </p>
+   </body>
+</html>