[Pki-devel] [PATCH] 0027..0029 support external authorization LDAP server

Fraser Tweedale ftweedal at redhat.com
Wed Mar 11 09:05:07 UTC 2015


These patches resolve https://fedorahosted.org/pki/ticket/1174

Regards,
Fraser
-------------- next part --------------
>From 4c9e18773d791d9384b8d386ba46c4270b025685 Mon Sep 17 00:00:00 2001
From: Christina Fu <cfu at redhat.com>
Date: Tue, 10 Mar 2015 02:06:02 -0400
Subject: [PATCH 27/29] Retrieve groups in UidPwdDirAuthentication plugin

---
 .../cms/authentication/DirBasedAuthentication.java |  39 +++-
 .../authentication/UidPwdDirAuthentication.java    | 213 ++++++++++++++++++++-
 2 files changed, 240 insertions(+), 12 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 f2d09df9e410ac817e2a90d4f82bbd4c488a8ab2..7607f23a80dc108c76aa62ae1cdf953c3a2ea3c2 100644
--- a/base/server/cms/src/com/netscape/cms/authentication/DirBasedAuthentication.java
+++ b/base/server/cms/src/com/netscape/cms/authentication/DirBasedAuthentication.java
@@ -74,6 +74,14 @@ public abstract class DirBasedAuthentication
     /* configuration parameter keys */
     protected static final String PROP_LDAP = "ldap";
     protected static final String PROP_BASEDN = "basedn";
+    protected static final String PROP_GROUPS_BASEDN = "groupsBasedn";
+    protected static final String PROP_GROUPS = "groups";
+    protected static final String PROP_GROUPS_DELIMITER = "groupsDelimiter";
+    protected static final String PROP_GROUP_OBJECT_CLASS = "groupObjectClass";
+    protected static final String PROP_GROUP_USERID_NAME = "groupUseridName";
+    protected static final String PROP_GROUPID_NAME = "groupidName";
+    protected static final String PROP_USERID_NAME = "useridName";
+    protected static final String PROP_SEARCH_GROUP_USER_BY_USERDN = "searchGroupUserByUserdn";
     protected static final String PROP_DNPATTERN = "dnpattern";
     protected static final String PROP_LDAPSTRINGATTRS = "ldapStringAttributes";
     protected static final String PROP_LDAPBYTEATTRS = "ldapByteAttributes";
@@ -94,6 +102,14 @@ public abstract class DirBasedAuthentication
 
     /* ldap base dn */
     protected String mBaseDN = null;
+    protected String mGroups = null; // e.g. "ou=Groups"
+    protected String mGroupsDelimiter = null; //regular expression
+    protected String mGroupsBaseDN = null; // in case it's different from mBaseDN
+    protected String mGroupObjectClass = null;
+    protected String mUserIDName = null;
+    protected String mGroupUserIDName = null;
+    protected String mGroupIDName = null;
+    protected boolean mSearchGroupUserByUserdn = true;
 
     /* factory of anonymous ldap connections */
     protected ILdapConnFactory mConnFactory = null;
@@ -243,10 +259,27 @@ public abstract class DirBasedAuthentication
 
         /* initialize ldap server configuration */
         mLdapConfig = mConfig.getSubStore(PROP_LDAP);
-        if (needBaseDN)
+        if (needBaseDN) {
             mBaseDN = mLdapConfig.getString(PROP_BASEDN);
-        if (needBaseDN && ((mBaseDN == null) || (mBaseDN.length() == 0) || (mBaseDN.trim().equals(""))))
-            throw new EPropertyNotFound(CMS.getUserMessage("CMS_BASE_GET_PROPERTY_FAILED", "basedn"));
+            if (mBaseDN == null || mBaseDN.trim().equals(""))
+                throw new EPropertyNotFound(CMS.getUserMessage("CMS_BASE_GET_PROPERTY_FAILED", "basedn"));
+            mGroupsBaseDN = mLdapConfig.getString(PROP_GROUPS_BASEDN, mBaseDN);
+            CMS.debug("DirBasedAuthentication: mGroupsBaseDN="+ mGroupsBaseDN);
+            mGroups= mLdapConfig.getString(PROP_GROUPS, "ou=groups");
+            CMS.debug("DirBasedAuthentication: mGroups="+ mGroups);
+            mGroupsDelimiter= mLdapConfig.getString(PROP_GROUPS_DELIMITER, "&&&");
+            CMS.debug("DirBasedAuthentication: mGroupsDelimiter="+ mGroupsDelimiter);
+            mGroupObjectClass = mLdapConfig.getString(PROP_GROUP_OBJECT_CLASS, "groupofuniquenames");
+            CMS.debug("DirBasedAuthentication: mGroupObjectClass="+ mGroupObjectClass);
+            mUserIDName = mLdapConfig.getString(PROP_USERID_NAME, "uid");
+            CMS.debug("DirBasedAuthentication: mUserIDName="+ mUserIDName);
+            mSearchGroupUserByUserdn = mLdapConfig.getBoolean(PROP_SEARCH_GROUP_USER_BY_USERDN, true);
+            CMS.debug("DirBasedAuthentication: mSearchGroupUserByUserdn="+ mSearchGroupUserByUserdn);
+            mGroupUserIDName = mLdapConfig.getString(PROP_GROUP_USERID_NAME, "cn");
+            CMS.debug("DirBasedAuthentication: mGroupUserIDName="+ mGroupUserIDName);
+            mGroupIDName = mLdapConfig.getString(PROP_GROUPID_NAME, "cn");
+            CMS.debug("DirBasedAuthentication: mGroupIDName="+ mGroupIDName);
+        }
         mConnFactory = CMS.getLdapAnonConnFactory();
         mConnFactory.init(mLdapConfig);
 
diff --git a/base/server/cms/src/com/netscape/cms/authentication/UidPwdDirAuthentication.java b/base/server/cms/src/com/netscape/cms/authentication/UidPwdDirAuthentication.java
index c85644d59eb4ab0354517140c623f3e36eb5d93c..f84d805d1c9e8ff08c58cac2fe2475f5d246e27d 100644
--- a/base/server/cms/src/com/netscape/cms/authentication/UidPwdDirAuthentication.java
+++ b/base/server/cms/src/com/netscape/cms/authentication/UidPwdDirAuthentication.java
@@ -22,6 +22,7 @@ import java.util.Enumeration;
 import java.util.Locale;
 import java.util.Vector;
 
+import netscape.ldap.LDAPAttribute;
 import netscape.ldap.LDAPConnection;
 import netscape.ldap.LDAPEntry;
 import netscape.ldap.LDAPException;
@@ -45,6 +46,7 @@ import com.netscape.certsrv.profile.IProfileAuthenticator;
 import com.netscape.certsrv.property.Descriptor;
 import com.netscape.certsrv.property.IDescriptor;
 import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.usrgrp.EUsrGrpException;
 
 /**
  * uid/pwd directory based authentication manager
@@ -59,7 +61,9 @@ public class UidPwdDirAuthentication extends DirBasedAuthentication
     public static final String CRED_UID = "uid";
     public static final String CRED_PWD = "pwd";
     protected static String[] mRequiredCreds = { CRED_UID, CRED_PWD };
-    public static final String USERID = "userid";
+
+    public static final String TOKEN_USERID = "userid";
+    public static final String TOKEN_GROUPS = "groups";
 
     /* Holds configuration parameters accepted by this implementation.
      * This list is passed to the configuration console so configuration
@@ -89,6 +93,139 @@ public class UidPwdDirAuthentication extends DirBasedAuthentication
     };
 
     /**
+     * Retrieves group base dn.
+     */
+    private String getGroupBaseDN() {
+        return mGroups + "," + mGroupsBaseDN;
+    }
+
+    /**
+     * List groups. only retrieves group names
+     */
+    public Enumeration<String> listGroups(LDAPConnection ldapconn, String filter) throws EUsrGrpException {
+        String method = "UidPwdDirAuthentication: listGroups:";
+        CMS.debug(method + " begins");
+        if (filter == null) {
+            return null;
+        }
+
+        try {
+            String attrs[] = new String[1];
+            attrs[0] = mGroupIDName;
+
+            LDAPSearchResults res =
+                ldapconn.search(getGroupBaseDN(), LDAPv2.SCOPE_SUB,
+                    "(&(objectclass=" +
+                    mGroupObjectClass +
+                    ")("+ mGroupIDName +"=" + filter + "))",
+                    attrs, false);
+
+            return buildGroups(res);
+        } catch (LDAPException e) {
+            String errMsg = "listGroups()" + e.toString();
+
+            if (e.getLDAPResultCode() == LDAPException.UNAVAILABLE) {
+                errMsg = "listGroups: " + "Internal DB is unavailable";
+            }
+            CMS.debug(method + e);
+        } finally {
+            CMS.debug(method + " ends");
+        }
+        return null;
+    }
+
+    protected Enumeration<String> buildGroups(LDAPSearchResults res) {
+        Vector<String> v = new Vector<>();
+
+        while (res.hasMoreElements()) {
+            LDAPEntry entry = (LDAPEntry) res.nextElement();
+            String groupName = null;
+                groupName = (String)entry.getAttribute(mGroupIDName).getStringValues().nextElement();
+
+            if (groupName != null)
+                v.addElement(groupName);
+        }
+        return v.elements();
+    }
+
+    /*
+     * userIdent could be either uid or userdn, depending on the
+     *    mSearchGroupUserByUserdn value
+     */
+    protected boolean isMemberOfLdapGroup(LDAPConnection ldapconn, String userIdent, String groupname)
+    {
+        /*
+         * e.g.
+         *  auths.instance.UserDirEnrollment.ldap.basedn=dc=dsdev,dc=sjc,dc=redhat,dc=com
+         *  auths.instance.UserDirEnrollment.ldap.groupObjectClass=groupofuniquenames
+         *  auths.instance.UserDirEnrollment.ldap.groups=ou=Groups
+         *  auths.instance.UserDirEnrollment.ldap.groupsBasedn=dc=dsdev,dc=sjc,dc=redhat,dc=com
+         *  auths.instance.UserDirEnrollment.ldap.groupidName=cn
+         *  auths.instance.UserDirEnrollment.ldap.useridName=uid
+         *  auths.instance.UserDirEnrollment.ldap.groupUseridName=cn
+         *  auths.instance.UserDirEnrollment.ldap.searchGroupUserByUserdn=false
+         *
+         *  where group = "directory administrators"
+         *        userIdent = "cfu"
+         *  would result in
+         *    basedn = "cn=directory administrators,ou=Groups,dc=dsdev,dc=sjc,dc=redhat,dc=com
+         */
+        String basedn = mGroupIDName + "="+groupname+"," + mGroups + "," +mGroupsBaseDN;
+        boolean founduser=false;
+        try {
+            // the group could potentially have many thousands
+            // of members, (many values of the uniquemember
+            // attribute). So, we don't want to fetch this
+            // list each time. We'll just fetch the CN.
+            String attrs[]= new String[1];
+            attrs[0] = mGroupUserIDName;
+
+            String filter = null;
+            if (mGroupObjectClass.equalsIgnoreCase("groupOfUniqueNames"))
+               if(mSearchGroupUserByUserdn)
+                   filter = "(uniquemember="+userIdent+")";
+               else
+                   filter = "(uniquemember=" + mGroupUserIDName +
+                       "="+userIdent+")";
+            else if (mGroupObjectClass.equalsIgnoreCase("groupOfNames"))
+               if(mSearchGroupUserByUserdn)
+                   filter = "(member="+userIdent+")";
+               else
+                   filter = "(member=" + mGroupUserIDName +
+                       "="+userIdent+")";
+            else {
+                CMS.debug("UidPwdDirAuthentication: isMemberOfLdapGroup: unrecognized mGroupObjectClass: " + mGroupObjectClass);
+                return false;
+            }
+
+            CMS.debug("UidPwdDirAuthentication: isMemberOfLdapGroup: search with basedn="+ basedn + " and filter =" + filter); 
+
+            LDAPSearchResults res =
+                ldapconn.search(basedn, LDAPv2.SCOPE_BASE,
+                       filter,
+                       attrs, false);
+            // If the result had at least one entry, we know
+            // that the filter matched, and so the user correctly
+            // authenticated.
+            if (res.hasMoreElements()) {
+                // actually read the entry
+                LDAPEntry entry = (LDAPEntry)res.nextElement();
+                founduser=true;
+            }
+            CMS.debug("UidPwdDirAuthentication: isMemberOfLdapGroup: "+ groupname + ":" + founduser);
+        } catch (LDAPException e) {
+           String errMsg =
+               "UidPwdDirAuthentication:isMemberOfLdapGroup: Could not find grou " +
+               groupname + ". Error "+e;
+           if (e.getLDAPResultCode() == LDAPException.UNAVAILABLE) {
+               errMsg = "UidPwdDirAuthentication:isMemberOfLdapGroup: "+"db unavailable";
+           }
+           CMS.debug(errMsg);
+        }
+        return founduser;
+    }
+
+    /**
      * Default constructor, initialization must follow.
      */
     public UidPwdDirAuthentication() {
@@ -131,18 +268,27 @@ public class UidPwdDirAuthentication extends DirBasedAuthentication
                 throw new EInvalidCredentials(CMS.getUserMessage("CMS_AUTHENTICATION_INVALID_CREDENTIAL"));
             }
 
+            /*
+             * first try and see if the directory server supports "memberOf"
+             * if so, use it, if not, then pull all groups to check
+             */
+            String attrs[] = {"memberOf"};
             // get user dn.
-            CMS.debug("Authenticating: Searching for UID=" + uid +
-                      " base DN=" + mBaseDN);
-            LDAPSearchResults res = conn.search(mBaseDN,
-                    LDAPv2.SCOPE_SUB, "(uid=" + uid + ")", null, false);
+            CMS.debug("UidPwdDirAuthentication: Authenticating: Searching for " +
+                    mUserIDName + "=" + uid + " base DN=" + mBaseDN);
+            LDAPSearchResults res = conn.search(
+                mBaseDN,
+                LDAPv2.SCOPE_SUB,
+                "(" + mUserIDName + "=" + uid + ")",
+                attrs,
+                false);
 
+            LDAPEntry entry = null;
             if (res.hasMoreElements()) {
-                //LDAPEntry entry = (LDAPEntry)res.nextElement();
-                LDAPEntry entry = res.next();
+                entry = res.next();
 
                 userdn = entry.getDN();
-                CMS.debug("Authenticating: Found User DN=" + userdn);
+                CMS.debug("UidPwdDirAuthentication: Authenticating: Found User DN=" + userdn);
             } else {
                 log(ILogger.LL_SECURITY, CMS.getLogMessage("CMS_AUTH_USER_NOT_EXIST", uid));
                 throw new EInvalidCredentials(CMS.getUserMessage("CMS_AUTHENTICATION_INVALID_CREDENTIAL"));
@@ -150,9 +296,58 @@ public class UidPwdDirAuthentication extends DirBasedAuthentication
 
             // bind as user dn and pwd - authenticates user with pwd.
             conn.authenticate(userdn, pwd);
+
+            LDAPAttribute attribute = entry.getAttribute("memberOf");
+            if ( attribute != null ) {
+                CMS.debug("UidPwdDirAuthentication: Authenticate: Found memberOf attribute");
+                String grpString = ""; // this goes into AuthToken
+                String[] e = attribute.getStringValueArray();
+                for (int i = 0; i < e.length; i++) {
+                    String group = e[i];
+                    CMS.debug("UidPwdDirAuthentication: Authenticate: Found user is a memberOf=" + group);
+                    if (grpString.length() != 0) {
+                        grpString += mGroupsDelimiter;
+                    }
+                    grpString += group;
+                }
+                // set groups in string delimited by PROP_GROUPS_DELIMITER
+                if (grpString != null && !grpString.equals("")) {
+                    token.set(TOKEN_GROUPS, grpString);
+                    CMS.debug("UidPwdDirAuthentication: authToken set with groups to: " + grpString);
+                }
+            } else {
+                CMS.debug("UidPwdDirAuthentication: Authenticate: memberOf attribute not found.");
+                // get list of groups, and get a list of those that this
+                //          uid belongs to
+                Enumeration<String> groups = null;
+
+                try {
+                    groups = listGroups(conn, "*");
+                } catch (Exception ex) {
+                    CMS.debug("UidPwdDirAuthentication: authenticate: failed listGroups():" + ex + ". ok to continue");
+                }
+                if (groups != null) {
+                    String grpString = ""; // this goes into AuthToken
+                    while (groups.hasMoreElements()) {
+                        String group = groups.nextElement();
+
+                        CMS.debug("UidPwdDirAuthentication: authenticate: checking to see if is member of:" + group);
+                        if (isMemberOfLdapGroup(conn, (mSearchGroupUserByUserdn)? userdn:uid, group) == true) {
+                            if (grpString.length() !=0 ) {
+                                grpString += mGroupsDelimiter;
+                            }
+                            grpString += group;
+                        }
+                    }
+                    // set groups in string delimited by PROP_GROUPS_DELIMITER 
+                    if (grpString != null && !grpString.equals(""))
+                        token.set(TOKEN_GROUPS, grpString);
+                }
+            }
+
             // set uid in the token.
             token.set(CRED_UID, uid);
-            token.set(USERID, uid);
+            token.set(TOKEN_USERID, uid);
 
             return userdn;
         } catch (ELdapException e) {
-- 
2.1.0

-------------- next part --------------
>From f7e381078f842cc8ab2fe630c2102d5dd3090cb0 Mon Sep 17 00:00:00 2001
From: Fraser Tweedale <frase at frase.id.au>
Date: Tue, 10 Mar 2015 02:07:06 -0400
Subject: [PATCH 28/29] Add groupsEnable config knob (disabled by default)

Add the 'groupsEnable' config knob to control whether group
information is retrieved and stored in the AuthToken by
UidPwdDirAuthentication.  Administrators need only incur the cost of
group retrieval if group information is needed.
---
 .../com/netscape/cms/authentication/DirBasedAuthentication.java   | 4 ++++
 .../com/netscape/cms/authentication/UidPwdDirAuthentication.java  | 8 +++++---
 2 files changed, 9 insertions(+), 3 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 7607f23a80dc108c76aa62ae1cdf953c3a2ea3c2..c4dd6650cfffc64924c037adb3a61ef92d9038c6 100644
--- a/base/server/cms/src/com/netscape/cms/authentication/DirBasedAuthentication.java
+++ b/base/server/cms/src/com/netscape/cms/authentication/DirBasedAuthentication.java
@@ -74,6 +74,7 @@ public abstract class DirBasedAuthentication
     /* configuration parameter keys */
     protected static final String PROP_LDAP = "ldap";
     protected static final String PROP_BASEDN = "basedn";
+    protected static final String PROP_GROUPS_ENABLE = "groupsEnable";
     protected static final String PROP_GROUPS_BASEDN = "groupsBasedn";
     protected static final String PROP_GROUPS = "groups";
     protected static final String PROP_GROUPS_DELIMITER = "groupsDelimiter";
@@ -102,6 +103,7 @@ public abstract class DirBasedAuthentication
 
     /* ldap base dn */
     protected String mBaseDN = null;
+    protected boolean mGroupsEnable = false;
     protected String mGroups = null; // e.g. "ou=Groups"
     protected String mGroupsDelimiter = null; //regular expression
     protected String mGroupsBaseDN = null; // in case it's different from mBaseDN
@@ -263,6 +265,8 @@ public abstract class DirBasedAuthentication
             mBaseDN = mLdapConfig.getString(PROP_BASEDN);
             if (mBaseDN == null || mBaseDN.trim().equals(""))
                 throw new EPropertyNotFound(CMS.getUserMessage("CMS_BASE_GET_PROPERTY_FAILED", "basedn"));
+            mGroupsEnable = mLdapConfig.getBoolean(PROP_GROUPS_ENABLE, false);
+            CMS.debug("DirBasedAuthentication: mGroupsEnable=" + (mGroupsEnable ? "true" : "false"));
             mGroupsBaseDN = mLdapConfig.getString(PROP_GROUPS_BASEDN, mBaseDN);
             CMS.debug("DirBasedAuthentication: mGroupsBaseDN="+ mGroupsBaseDN);
             mGroups= mLdapConfig.getString(PROP_GROUPS, "ou=groups");
diff --git a/base/server/cms/src/com/netscape/cms/authentication/UidPwdDirAuthentication.java b/base/server/cms/src/com/netscape/cms/authentication/UidPwdDirAuthentication.java
index f84d805d1c9e8ff08c58cac2fe2475f5d246e27d..76ae8ce583be23d6927d1bdf35e234766d83091a 100644
--- a/base/server/cms/src/com/netscape/cms/authentication/UidPwdDirAuthentication.java
+++ b/base/server/cms/src/com/netscape/cms/authentication/UidPwdDirAuthentication.java
@@ -272,7 +272,9 @@ public class UidPwdDirAuthentication extends DirBasedAuthentication
              * first try and see if the directory server supports "memberOf"
              * if so, use it, if not, then pull all groups to check
              */
-            String attrs[] = {"memberOf"};
+            String emptyAttrs[] = {};
+            String groupAttrs[] = {"memberOf"};
+
             // get user dn.
             CMS.debug("UidPwdDirAuthentication: Authenticating: Searching for " +
                     mUserIDName + "=" + uid + " base DN=" + mBaseDN);
@@ -280,7 +282,7 @@ public class UidPwdDirAuthentication extends DirBasedAuthentication
                 mBaseDN,
                 LDAPv2.SCOPE_SUB,
                 "(" + mUserIDName + "=" + uid + ")",
-                attrs,
+                (mGroupsEnable ? groupAttrs : emptyAttrs),
                 false);
 
             LDAPEntry entry = null;
@@ -315,7 +317,7 @@ public class UidPwdDirAuthentication extends DirBasedAuthentication
                     token.set(TOKEN_GROUPS, grpString);
                     CMS.debug("UidPwdDirAuthentication: authToken set with groups to: " + grpString);
                 }
-            } else {
+            } else if (mGroupsEnable) {
                 CMS.debug("UidPwdDirAuthentication: Authenticate: memberOf attribute not found.");
                 // get list of groups, and get a list of those that this
                 //          uid belongs to
-- 
2.1.0

-------------- next part --------------
>From c747a606e34abdfa0f6749f25f1b23b6a9bc6150 Mon Sep 17 00:00:00 2001
From: Fraser Tweedale <frase at frase.id.au>
Date: Wed, 11 Mar 2015 04:55:10 -0400
Subject: [PATCH 29/29] Update group evaluator to check all groups on token

The GroupAccessEvaluator only checks the "gid" when evaluating an
ACL.  Update it to also read a list of groups from the AuthToken and
check those groups.

The "gid" and "groups" are merged into a single collection, if the
ACL operation is "=" the collection is checked under disjunction,
and if the operation is "!=", then conjunction.

Also update the UidPwdDirAuthentication plugin to save the group
list to the AuthToken as a String[] rather than a delimited String.
---
 .../certsrv/authentication/IAuthToken.java         |  3 ++
 .../authentication/UidPwdDirAuthentication.java    | 56 +++++++---------------
 .../cms/evaluators/GroupAccessEvaluator.java       | 33 +++++++++----
 3 files changed, 44 insertions(+), 48 deletions(-)

diff --git a/base/common/src/com/netscape/certsrv/authentication/IAuthToken.java b/base/common/src/com/netscape/certsrv/authentication/IAuthToken.java
index 3c03cc1f5e85a92237067fde98e20d9f13a0b947..c552c4ce24730dc84906c95131f8d5ea9392d883 100644
--- a/base/common/src/com/netscape/certsrv/authentication/IAuthToken.java
+++ b/base/common/src/com/netscape/certsrv/authentication/IAuthToken.java
@@ -38,6 +38,9 @@ public interface IAuthToken {
      * Constant for userid.
      */
     public static final String USER_ID = "userid";
+    public static final String UID = "uid";
+    public static final String GID = "gid";
+    public static final String GROUPS = "groups";
 
     /**
      * Sets an attribute value within this AttrSet.
diff --git a/base/server/cms/src/com/netscape/cms/authentication/UidPwdDirAuthentication.java b/base/server/cms/src/com/netscape/cms/authentication/UidPwdDirAuthentication.java
index 76ae8ce583be23d6927d1bdf35e234766d83091a..552b187ae12059a386e82cec76dfa13cb91e3d64 100644
--- a/base/server/cms/src/com/netscape/cms/authentication/UidPwdDirAuthentication.java
+++ b/base/server/cms/src/com/netscape/cms/authentication/UidPwdDirAuthentication.java
@@ -62,9 +62,6 @@ public class UidPwdDirAuthentication extends DirBasedAuthentication
     public static final String CRED_PWD = "pwd";
     protected static String[] mRequiredCreds = { CRED_UID, CRED_PWD };
 
-    public static final String TOKEN_USERID = "userid";
-    public static final String TOKEN_GROUPS = "groups";
-
     /* Holds configuration parameters accepted by this implementation.
      * This list is passed to the configuration console so configuration
      * for instances of this implementation can be configured through the
@@ -102,7 +99,7 @@ public class UidPwdDirAuthentication extends DirBasedAuthentication
     /**
      * List groups. only retrieves group names
      */
-    public Enumeration<String> listGroups(LDAPConnection ldapconn, String filter) throws EUsrGrpException {
+    private Vector<String> listGroups(LDAPConnection ldapconn, String filter) throws EUsrGrpException {
         String method = "UidPwdDirAuthentication: listGroups:";
         CMS.debug(method + " begins");
         if (filter == null) {
@@ -134,7 +131,7 @@ public class UidPwdDirAuthentication extends DirBasedAuthentication
         return null;
     }
 
-    protected Enumeration<String> buildGroups(LDAPSearchResults res) {
+    private Vector<String> buildGroups(LDAPSearchResults res) {
         Vector<String> v = new Vector<>();
 
         while (res.hasMoreElements()) {
@@ -145,7 +142,7 @@ public class UidPwdDirAuthentication extends DirBasedAuthentication
             if (groupName != null)
                 v.addElement(groupName);
         }
-        return v.elements();
+        return v;
     }
 
     /*
@@ -302,54 +299,35 @@ public class UidPwdDirAuthentication extends DirBasedAuthentication
             LDAPAttribute attribute = entry.getAttribute("memberOf");
             if ( attribute != null ) {
                 CMS.debug("UidPwdDirAuthentication: Authenticate: Found memberOf attribute");
-                String grpString = ""; // this goes into AuthToken
-                String[] e = attribute.getStringValueArray();
-                for (int i = 0; i < e.length; i++) {
-                    String group = e[i];
-                    CMS.debug("UidPwdDirAuthentication: Authenticate: Found user is a memberOf=" + group);
-                    if (grpString.length() != 0) {
-                        grpString += mGroupsDelimiter;
-                    }
-                    grpString += group;
-                }
-                // set groups in string delimited by PROP_GROUPS_DELIMITER
-                if (grpString != null && !grpString.equals("")) {
-                    token.set(TOKEN_GROUPS, grpString);
-                    CMS.debug("UidPwdDirAuthentication: authToken set with groups to: " + grpString);
-                }
+                String[] groups = attribute.getStringValueArray();
+                token.set(IAuthToken.GROUPS, groups);
+                CMS.debug("UidPwdDirAuthentication: authToken set with groups to: " + groups.toString());
             } else if (mGroupsEnable) {
                 CMS.debug("UidPwdDirAuthentication: Authenticate: memberOf attribute not found.");
                 // get list of groups, and get a list of those that this
                 //          uid belongs to
-                Enumeration<String> groups = null;
+                Vector<String> allGroups = null;
+                Vector<String> groups = new Vector<>();
 
                 try {
-                    groups = listGroups(conn, "*");
+                    allGroups = listGroups(conn, "*");
                 } catch (Exception ex) {
                     CMS.debug("UidPwdDirAuthentication: authenticate: failed listGroups():" + ex + ". ok to continue");
                 }
                 if (groups != null) {
-                    String grpString = ""; // this goes into AuthToken
-                    while (groups.hasMoreElements()) {
-                        String group = groups.nextElement();
-
-                        CMS.debug("UidPwdDirAuthentication: authenticate: checking to see if is member of:" + group);
-                        if (isMemberOfLdapGroup(conn, (mSearchGroupUserByUserdn)? userdn:uid, group) == true) {
-                            if (grpString.length() !=0 ) {
-                                grpString += mGroupsDelimiter;
-                            }
-                            grpString += group;
-                        }
+                    for (String group : allGroups) {
+                        CMS.debug("UidPwdDirAuthentication: authenticate: checking to see if is member of: " + group);
+                        if (isMemberOfLdapGroup(conn, (mSearchGroupUserByUserdn ? userdn : uid), group))
+                            groups.add(group);
                     }
-                    // set groups in string delimited by PROP_GROUPS_DELIMITER 
-                    if (grpString != null && !grpString.equals(""))
-                        token.set(TOKEN_GROUPS, grpString);
+                    String[] groupsArray = new String[groups.size()];
+                    token.set(IAuthToken.GROUPS, groups.toArray(groupsArray));
                 }
             }
 
             // set uid in the token.
-            token.set(CRED_UID, uid);
-            token.set(TOKEN_USERID, uid);
+            token.set(IAuthToken.UID, uid);
+            token.set(IAuthToken.USER_ID, uid);
 
             return userdn;
         } catch (ELdapException e) {
diff --git a/base/server/cms/src/com/netscape/cms/evaluators/GroupAccessEvaluator.java b/base/server/cms/src/com/netscape/cms/evaluators/GroupAccessEvaluator.java
index e8a32d752be327bf8cbb4c45d5717f84900fbc4a..a21311b56bb74705b3467a990e0ad11007907c8d 100644
--- a/base/server/cms/src/com/netscape/cms/evaluators/GroupAccessEvaluator.java
+++ b/base/server/cms/src/com/netscape/cms/evaluators/GroupAccessEvaluator.java
@@ -17,6 +17,7 @@
 // --- END COPYRIGHT BLOCK ---
 package com.netscape.cms.evaluators;
 
+import java.util.Vector;
 import com.netscape.certsrv.apps.CMS;
 import com.netscape.certsrv.authentication.IAuthToken;
 import com.netscape.certsrv.base.EBaseException;
@@ -101,9 +102,9 @@ public class GroupAccessEvaluator implements IAccessEvaluator {
             // should define "uid" at a common place
             String uid = null;
 
-            uid = authToken.getInString("userid");
+            uid = authToken.getInString(IAuthToken.USER_ID);
             if (uid == null) {
-                uid = authToken.getInString("uid");
+                uid = authToken.getInString(IAuthToken.UID);
                 if (uid == null) {
                     CMS.debug("GroupAccessEvaluator: evaluate: uid null");
                     log(ILogger.LL_FAILURE, CMS.getLogMessage("EVALUTOR_UID_NULL"));
@@ -112,15 +113,29 @@ public class GroupAccessEvaluator implements IAccessEvaluator {
             }
             CMS.debug("GroupAccessEvaluator: evaluate: uid=" + uid + " value=" + value);
 
-            String groupname = authToken.getInString("gid");
+            Vector<String> groups = new Vector<>();
 
-            if (groupname != null) {
-                CMS.debug("GroupAccessEvaluator: evaluate: authToken gid=" + groupname);
-                if (op.equals("=")) {
-                    return groupname.equals(Utils.stripQuotes(value));
-                } else if (op.equals("!=")) {
-                    return !groupname.equals(Utils.stripQuotes(value));
+            String gid = authToken.getInString(IAuthToken.GID);
+            if (gid != null)
+                groups.add(gid);
+
+            String[] groupsArray = authToken.getInStringArray(IAuthToken.GROUPS);
+            if (groupsArray != null) {
+                for (int i = 0; i < groupsArray.length; i++)
+                    groups.add(groupsArray[i]);
+            }
+
+            if (groups.size() > 0) {
+                boolean matched = false;
+                for (String group : groups) {
+                    CMS.debug("GroupAccessEvaluator: evaluate: authToken gid=" + group);
+                    if (group.equals(Utils.stripQuotes(value)))
+                        matched = true;
                 }
+                if (op.equals("="))
+                    return matched;
+                else if (op.equals("!="))
+                    return !matched;
             } else {
                 CMS.debug("GroupAccessEvaluator: evaluate: no gid in authToken");
                 IUser id = null;
-- 
2.1.0



More information about the Pki-devel mailing list