>From 96340425ab69fb7e416ffeebace1c357f2fc802e Mon Sep 17 00:00:00 2001
From: Christina Fu <cfu@redhat.com>
Date: Wed, 5 Aug 2015 16:21:51 -0700
Subject: [PATCH] Ticket 1531 Directory auth plugin requires LDAP anonymous
 binds - This patch adds a feature to allow a directory based authentication
 plugin to use bound ldap conneciton instead of anonymous. Two files need to
 be edited 1. <instance>/conf/password.conf   add a "tag" and the password of
 the binding user dn to the file   e.g. externalLDAP=password123 2.
 <instance>/ca/CS.cfg   add the tag to cms.passwordlist:   e.g.
 cms.passwordlist=internaldb,replicationdb,externalLDAP   add the prefix of
 the auths entry for the authentication instance   e.g.
 externalLDAP.prefix=auths.instance.UserDirEnrollment   add relevant entries
 to the authenticaiton instance   e.g.
 auths.instance.UserDirEnrollment.ldap.ldapBoundConn=true       
 auths.instance.UserDirEnrollment.ldap.ldapauth.authtype=BasicAuth       
 auths.instance.UserDirEnrollment.ldap.ldapauth.bindDN=uid=rhcs,ou=serviceaccounts,dc=EXAMPLE,dc=com
       
 auths.instance.UserDirEnrollment.ldap.ldapauth.bindPWPrompt=externalLDAP

---
 .../cms/authentication/DirBasedAuthentication.java | 30 ++++++++++++++++++--
 .../src/com/netscape/cmscore/apps/CMSEngine.java   | 33 ++++++++++++++++++++--
 2 files changed, 58 insertions(+), 5 deletions(-)

diff --git a/base/server/cms/src/com/netscape/cms/authentication/DirBasedAuthentication.java b/base/server/cms/src/com/netscape/cms/authentication/DirBasedAuthentication.java
index a8a95284df14bd287f7a9a0f5ccba43bf174c4a8..ef74457d23b4182905894be847a44b8ca3e4f6af 100644
--- a/base/server/cms/src/com/netscape/cms/authentication/DirBasedAuthentication.java
+++ b/base/server/cms/src/com/netscape/cms/authentication/DirBasedAuthentication.java
@@ -84,6 +84,7 @@ public abstract class DirBasedAuthentication
     protected static final String PROP_DNPATTERN = "dnpattern";
     protected static final String PROP_LDAPSTRINGATTRS = "ldapStringAttributes";
     protected static final String PROP_LDAPBYTEATTRS = "ldapByteAttributes";
+    protected static final String PROP_LDAP_BOUND_CONN = "ldapBoundConn";
 
     // members
 
@@ -110,6 +111,7 @@ public abstract class DirBasedAuthentication
     /* whether to search for member=<userDN> or member=<mGroupUserIdName>=<uid> */
     protected boolean mSearchGroupUserByUserdn = true;
 
+    protected boolean mBoundConnEnable = false;
     /* factory of anonymous ldap connections */
     protected ILdapConnFactory mConnFactory = null;
 
@@ -277,8 +279,15 @@ public abstract class DirBasedAuthentication
             mGroupUserIDName = mLdapConfig.getString(PROP_GROUP_USERID_NAME, "cn");
             CMS.debug("DirBasedAuthentication: mGroupUserIDName="+ mGroupUserIDName);
         }
-        mConnFactory = CMS.getLdapAnonConnFactory("DirBasedAuthentication");
-        mConnFactory.init(mLdapConfig);
+        mBoundConnEnable = mLdapConfig.getBoolean(PROP_LDAP_BOUND_CONN, false);
+        CMS.debug("DirBasedAuthentication: mBoundConnEnable =" + (mBoundConnEnable ? "true" : "false"));
+        if (mBoundConnEnable) {
+            mConnFactory = CMS.getLdapBoundConnFactory("DirBasedAuthentication");
+        } else {
+            mConnFactory = CMS.getLdapAnonConnFactory("DirBasedAuthentication");
+        }
+        if (mConnFactory != null) // else can try again later when needed
+            mConnFactory.init(mLdapConfig);
 
         /* initialize dn pattern */
         String pattern = mConfig.getString(PROP_DNPATTERN, null);
@@ -372,16 +381,31 @@ public abstract class DirBasedAuthentication
         String userdn = null;
         LDAPConnection conn = null;
         AuthToken authToken = new AuthToken(this);
+        String method = "DirBasedAuthentication: authenticate:";
 
+        CMS.debug(method + " begins...mBoundConnEnable=" + mBoundConnEnable);
         try {
             if (mConnFactory == null) {
-                conn = null;
+                CMS.debug(method + " mConnFactory null, getting conn factory");
+                if (mBoundConnEnable) {
+                    mConnFactory = CMS.getLdapBoundConnFactory("DirBasedAuthentication");
+                } else {
+                    mConnFactory = CMS.getLdapAnonConnFactory("DirBasedAuthentication");
+                }
+                if (mConnFactory != null) {
+                    mConnFactory.init(mLdapConfig);
+                    CMS.debug(method + " mConnFactory gotten, calling getConn");
+                    conn = mConnFactory.getConn();
+                }
             } else {
+                CMS.debug(method + " mConnFactory not null, calling getConn");
                 conn = mConnFactory.getConn();
             }
 
             // authenticate the user and get a user entry.
+            CMS.debug(method + " before authenticate() call");
             userdn = authenticate(conn, authCred, authToken);
+            CMS.debug(method + " after authenticate() call");
             authToken.set(USER_DN, userdn);
 
             // formulate the cert info.
diff --git a/base/server/cmscore/src/com/netscape/cmscore/apps/CMSEngine.java b/base/server/cmscore/src/com/netscape/cmscore/apps/CMSEngine.java
index fa2c8147f401d19836e52737b99be0ac1f108298..1f13c8c0d49e4f8391c5cf471980e43ec8dd0338 100644
--- a/base/server/cmscore/src/com/netscape/cmscore/apps/CMSEngine.java
+++ b/base/server/cmscore/src/com/netscape/cmscore/apps/CMSEngine.java
@@ -331,6 +331,7 @@ public class CMSEngine implements ICMSEngine {
     }
 
     public void initializePasswordStore(IConfigStore config) throws EBaseException, IOException {
+        System.out.println("CMSEngine.initializePasswordStore() begins");
         // create and initialize mPasswordStore
         getPasswordStore();
 
@@ -345,6 +346,7 @@ public class CMSEngine implements ICMSEngine {
             String binddn;
             String authType;
             LdapConnInfo connInfo = null;
+            System.out.println("CMSEngine.initializePasswordStore(): tag=" + tag);
 
             if (tag.equals("internaldb")) {
                 authType = config.getString("internaldb.ldapauth.authtype", "BasicAuth");
@@ -382,8 +384,35 @@ public class CMSEngine implements ICMSEngine {
                 binddn = config.getString("ca.publish.ldappublish.ldap.ldapauth.bindDN");
 
             } else {
-                // ignore any others for now
-                continue;
+                /*
+                 * This section assumes a generic format of
+                 * <prefix>.ldap.xxx
+                 * where <prefix> is specified under the tag substore
+                 *
+                 * e.g.  if tag = "externalLDAP"
+                 *   cms.passwordlist=...,externalLDAP
+                 *   externalLDAP.prefix=auths.instance.UserDirEnrollment
+                 *
+                 *   auths.instance.UserDirEnrollment.ldap.ldapauth.authtype=BasicAuth
+                 *   auths.instance.UserDirEnrollment.ldap.ldapauth.bindDN=cn=Corporate Directory Manager
+                 *   auths.instance.UserDirEnrollment.ldap.ldapauth.bindPWPrompt=externalLDAP
+                 *   auths.instance.UserDirEnrollment.ldap.ldapconn.host=host.example.com
+                 *   auths.instance.UserDirEnrollment.ldap.ldapconn.port=389
+                 *   auths.instance.UserDirEnrollment.ldap.ldapconn.secureConn=false
+                 */
+                String prefix = config.getString(tag + ".prefix");
+                System.out.println("CMSEngine.initializePasswordStore(): prefix=" + prefix);
+                authType = config.getString(prefix +".ldap.ldapauth.authtype", "BasicAuth");
+                System.out.println("CMSEngine.initializePasswordStore(): authType " + authType);
+                if (!authType.equals("BasicAuth"))
+                    continue;
+
+                connInfo = new LdapConnInfo(
+                        config.getString(prefix + ".ldap.ldapconn.host"),
+                        config.getInteger(prefix + ".ldap.ldapconn.port"),
+                        config.getBoolean(prefix + ".ldap.ldapconn.secureConn"));
+
+                binddn = config.getString(prefix + ".ldap.ldapauth.bindDN");
             }
 
             do {
-- 
1.8.4.2

