You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ranger.apache.org by sp...@apache.org on 2017/09/07 22:06:48 UTC
ranger git commit: RANGER-1735: Support representing nested group
memberships in Ranger Admin --ranger-0.7 branch
Repository: ranger
Updated Branches:
refs/heads/ranger-0.7 ab0fa6f31 -> f780aba3e
RANGER-1735: Support representing nested group memberships in Ranger Admin --ranger-0.7 branch
Project: http://git-wip-us.apache.org/repos/asf/ranger/repo
Commit: http://git-wip-us.apache.org/repos/asf/ranger/commit/f780aba3
Tree: http://git-wip-us.apache.org/repos/asf/ranger/tree/f780aba3
Diff: http://git-wip-us.apache.org/repos/asf/ranger/diff/f780aba3
Branch: refs/heads/ranger-0.7
Commit: f780aba3e717b7276e0a69f7c23734052b281f30
Parents: ab0fa6f
Author: Sailaja Polavarapu <sp...@hortonworks.com>
Authored: Thu Sep 7 14:07:52 2017 -0700
Committer: Sailaja Polavarapu <sp...@hortonworks.com>
Committed: Thu Sep 7 14:07:52 2017 -0700
----------------------------------------------------------------------
.../process/LdapDeltaUserGroupBuilder.java | 309 +++++++++++++-----
.../process/LdapUserGroupBuilder.java | 322 +++++++++++++++----
.../config/UserGroupSyncConfig.java | 38 ++-
.../ranger/usergroupsync/TestLdapUserGroup.java | 11 +-
ugsync/src/test/resources/ADSchema.ldif | 2 +
.../src/test/resources/ranger-ugsync-site.xml | 5 +
6 files changed, 532 insertions(+), 155 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ranger/blob/f780aba3/ugsync/src/main/java/org/apache/ranger/ldapusersync/process/LdapDeltaUserGroupBuilder.java
----------------------------------------------------------------------
diff --git a/ugsync/src/main/java/org/apache/ranger/ldapusersync/process/LdapDeltaUserGroupBuilder.java b/ugsync/src/main/java/org/apache/ranger/ldapusersync/process/LdapDeltaUserGroupBuilder.java
index d27a217..394bde2 100644
--- a/ugsync/src/main/java/org/apache/ranger/ldapusersync/process/LdapDeltaUserGroupBuilder.java
+++ b/ugsync/src/main/java/org/apache/ranger/ldapusersync/process/LdapDeltaUserGroupBuilder.java
@@ -49,6 +49,8 @@ import javax.naming.ldap.PagedResultsResponseControl;
import javax.naming.ldap.StartTlsRequest;
import javax.naming.ldap.StartTlsResponse;
+import org.apache.commons.collections.BidiMap;
+import org.apache.commons.collections.bidimap.DualHashBidiMap;
import org.apache.log4j.Logger;
import org.apache.ranger.unixusersync.config.UserGroupSyncConfig;
import org.apache.ranger.usergroupsync.AbstractUserGroupSource;
@@ -98,6 +100,7 @@ public class LdapDeltaUserGroupBuilder extends AbstractUserGroupSource {
private SearchControls groupSearchControls;
private String groupMemberAttributeName;
private String groupNameAttribute;
+ private int groupHierarchyLevels;
private LdapContext ldapContext;
StartTlsResponse tls;
@@ -110,21 +113,22 @@ public class LdapDeltaUserGroupBuilder extends AbstractUserGroupSource {
private boolean groupUserMapSyncEnabled = false;
//private Map<String, UserInfo> userGroupMap;
-
- private Table<String, String, String> groupUserTable;
+
+ private Table<String, String, String> groupUserTable;
private Map<String, String> userNameMap;
+ private BidiMap groupNameMap;
public static void main(String[] args) throws Throwable {
LdapDeltaUserGroupBuilder ugBuilder = new LdapDeltaUserGroupBuilder();
ugBuilder.init();
}
-
+
public LdapDeltaUserGroupBuilder() {
super();
LOG.info("LdapDeltaUserGroupBuilder created");
-
+
String userNameCaseConversion = config.getUserNameCaseConversion();
-
+
if (UserGroupSyncConfig.UGSYNC_NONE_CASE_CONVERSION_VALUE.equalsIgnoreCase(userNameCaseConversion)) {
userNameCaseConversionFlag = false;
}
@@ -132,9 +136,9 @@ public class LdapDeltaUserGroupBuilder extends AbstractUserGroupSource {
userNameCaseConversionFlag = true;
userNameLowerCaseFlag = UserGroupSyncConfig.UGSYNC_LOWER_CASE_CONVERSION_VALUE.equalsIgnoreCase(userNameCaseConversion);
}
-
+
String groupNameCaseConversion = config.getGroupNameCaseConversion();
-
+
if (UserGroupSyncConfig.UGSYNC_NONE_CASE_CONVERSION_VALUE.equalsIgnoreCase(groupNameCaseConversion)) {
groupNameCaseConversionFlag = false;
}
@@ -145,7 +149,7 @@ public class LdapDeltaUserGroupBuilder extends AbstractUserGroupSource {
}
@Override
- public void init() throws Throwable{
+ public void init() throws Throwable{
deltaSyncUserTime = 0;
deltaSyncGroupTime = 0;
DateFormat dateFormat = new SimpleDateFormat("yyyyMMddhhmmss");
@@ -154,7 +158,7 @@ public class LdapDeltaUserGroupBuilder extends AbstractUserGroupSource {
userNameMap = new HashMap<String, String>();
setConfig();
}
-
+
private void createLdapContext() throws Throwable {
Properties env = new Properties();
env.put(Context.INITIAL_CONTEXT_FACTORY,
@@ -182,7 +186,7 @@ public class LdapDeltaUserGroupBuilder extends AbstractUserGroupSource {
ldapContext.addToEnvironment(Context.SECURITY_AUTHENTICATION, ldapAuthenticationMechanism);
ldapContext.addToEnvironment(Context.REFERRAL, ldapReferral);
}
-
+
private void setConfig() throws Throwable {
LOG.info("LdapDeltaUserGroupBuilder initialization started");
@@ -196,14 +200,14 @@ public class LdapDeltaUserGroupBuilder extends AbstractUserGroupSource {
ldapAuthenticationMechanism = config.getLdapAuthenticationMechanism();
ldapReferral = config.getContextReferral();
searchBase = config.getSearchBase();
-
+
userSearchBase = config.getUserSearchBase().split(";");
userSearchScope = config.getUserSearchScope();
userObjectClass = config.getUserObjectClass();
userSearchFilter = config.getUserSearchFilter();
-
+
userNameAttribute = config.getUserNameAttribute();
-
+
Set<String> userSearchAttributes = new HashSet<String>();
userSearchAttributes.add(userNameAttribute);
// For Group based search, user's group name attribute should not be added to the user search attributes
@@ -229,6 +233,7 @@ public class LdapDeltaUserGroupBuilder extends AbstractUserGroupSource {
groupSearchFilter = config.getGroupSearchFilter();
groupMemberAttributeName = config.getUserGroupMemberAttributeName();
groupNameAttribute = config.getGroupNameAttribute();
+ groupHierarchyLevels = config.getGroupHierarchyLevels();
extendedGroupSearchFilter = "(&" + extendedGroupSearchFilter + "(|(" + groupMemberAttributeName + "={0})(" + groupMemberAttributeName + "={1})))";
groupUserMapSyncEnabled = config.isGroupUserMapSyncEnabled();
@@ -279,7 +284,7 @@ public class LdapDeltaUserGroupBuilder extends AbstractUserGroupSource {
}
}
-
+
private void closeLdapContext() throws Throwable {
if (tls != null) {
tls.close();
@@ -288,7 +293,7 @@ public class LdapDeltaUserGroupBuilder extends AbstractUserGroupSource {
ldapContext.close();
}
}
-
+
@Override
public boolean isChanged() {
// we do not want to get the full ldap dit and check whether anything has changed
@@ -299,27 +304,39 @@ public class LdapDeltaUserGroupBuilder extends AbstractUserGroupSource {
public void updateSink(UserGroupSink sink) throws Throwable {
LOG.info("LdapDeltaUserGroupBuilder updateSink started");
//userGroupMap = new HashMap<String, UserInfo>();
- groupUserTable = HashBasedTable.create();
- if (!groupSearchFirstEnabled) {
+ groupUserTable = HashBasedTable.create();
+ groupNameMap = new DualHashBidiMap();
+ if (!groupSearchFirstEnabled) {
LOG.info("Performing user search first");
getUsers(sink);
if (groupSearchEnabled) {
getGroups(sink);
}
//LOG.debug("Total No. of users saved = " + groupUserTable.columnKeySet().size());
-
+
} else {
LOG.info("Performing Group search first");
getGroups(sink);
if (userSearchEnabled) {
LOG.info("User search is enabled and hence computing user membership.");
getUsers(sink);
- }
+ }
}
if (groupUserTable.isEmpty()) {
//System.out.println("groupUserTable is empty!!");
return;
}
+
+ if (groupHierarchyLevels > 0) {
+ LOG.info("Going through group hierarchy for nested group evaluation");
+ Set<String> groupFullNames = groupNameMap.keySet();
+ for(String group : groupFullNames) {
+ Set<String> nextLevelGroups = groupUserTable.column(group).keySet();
+ goUpGroupHierarchy(nextLevelGroups, groupHierarchyLevels-1, groupNameMap.get(group).toString());
+ }
+ LOG.info("Completed group hierarchy computation");
+ }
+
Iterator<String> groupUserTableIterator = groupUserTable.rowKeySet().iterator();
while (groupUserTableIterator.hasNext()) {
String groupName = groupUserTableIterator.next();
@@ -327,12 +344,12 @@ public class LdapDeltaUserGroupBuilder extends AbstractUserGroupSource {
Map<String,String> groupUsersMap = groupUserTable.row(groupName);
Set<String> userSet = new HashSet<String>();
for(Map.Entry<String, String> entry : groupUsersMap.entrySet()){
- //String transformUserName = userNameTransform(entry.getKey());
+ //String transformUserName = userNameTransform(entry.getKey());
userSet.add(entry.getValue());
}
List<String> userList = new ArrayList<>(userSet);
String transformGroupName = groupNameTransform(groupName);
- try {
+ try {
sink.addOrUpdateGroup(transformGroupName, userList);
} catch (Throwable t) {
LOG.error("sink.addOrUpdateGroup failed with exception: " + t.getMessage()
@@ -341,7 +358,7 @@ public class LdapDeltaUserGroupBuilder extends AbstractUserGroupSource {
}
}
}
-
+
private void getUsers(UserGroupSink sink) throws Throwable {
NamingEnumeration<SearchResult> userSearchResultEnum = null;
NamingEnumeration<SearchResult> groupSearchResultEnum = null;
@@ -355,7 +372,7 @@ public class LdapDeltaUserGroupBuilder extends AbstractUserGroupSource {
}
DateFormat dateFormat = new SimpleDateFormat("yyyyMMddhhmmss");
extendedUserSearchFilter = "(objectclass=" + userObjectClass + ")(|(uSNChanged>=" + deltaSyncUserTime + ")(modifyTimestamp>=" + deltaSyncUserTimeStamp + "Z))";
-
+
if (userSearchFilter != null && !userSearchFilter.trim().isEmpty()) {
String customFilter = userSearchFilter.trim();
if (!customFilter.startsWith("(")) {
@@ -380,7 +397,7 @@ public class LdapDeltaUserGroupBuilder extends AbstractUserGroupSource {
userSearchResultEnum = ldapContext
.search(userSearchBase[ou], extendedUserSearchFilter,
userSearchControls);
-
+
while (userSearchResultEnum.hasMore()) {
// searchResults contains all the user entries
final SearchResult userEntry = userSearchResultEnum.next();
@@ -410,7 +427,7 @@ public class LdapDeltaUserGroupBuilder extends AbstractUserGroupSource {
}
continue;
}
-
+
String userFullName = (userEntry.getNameInNamespace()).toLowerCase();
String userName = (String) userNameAttr.get();
@@ -421,7 +438,7 @@ public class LdapDeltaUserGroupBuilder extends AbstractUserGroupSource {
}
continue;
}
-
+
Attribute timeStampAttr = attributes.get("uSNChanged");
if (timeStampAttr != null) {
String uSNChangedVal = (String) timeStampAttr.get();
@@ -434,7 +451,7 @@ public class LdapDeltaUserGroupBuilder extends AbstractUserGroupSource {
timeStampAttr = attributes.get("modifytimestamp");
if (timeStampAttr != null) {
String timeStampVal = (String) timeStampAttr.get();
- Date parseDate = dateFormat.parse(timeStampVal);
+ Date parseDate = dateFormat.parse(timeStampVal);
long currentDeltaSyncTime = parseDate.getTime();
LOG.info("timeStampVal = " + timeStampVal + "and currentDeltaSyncTime = " + currentDeltaSyncTime);
if (currentDeltaSyncTime > highestdeltaSyncUserTime) {
@@ -475,7 +492,7 @@ public class LdapDeltaUserGroupBuilder extends AbstractUserGroupSource {
List<String> groupList = new ArrayList<String>(groups);
try {
sink.addOrUpdateUser(transformUserName, groupList);
-
+
} catch (Throwable t) {
LOG.error("sink.addOrUpdateUserGroups failed with exception: " + t.getMessage()
+ ", for user: " + transformUserName + " and groups: " + groupList);
@@ -575,9 +592,11 @@ public class LdapDeltaUserGroupBuilder extends AbstractUserGroupSource {
closeLdapContext();
}
}
-
+
private void getGroups(UserGroupSink sink) throws Throwable {
NamingEnumeration<SearchResult> groupSearchResultEnum = null;
+ DateFormat dateFormat = new SimpleDateFormat("yyyyMMddhhmmss");
+ long highestdeltaSyncGroupTime = deltaSyncGroupTime;
try {
createLdapContext();
int total;
@@ -594,12 +613,10 @@ public class LdapDeltaUserGroupBuilder extends AbstractUserGroupSource {
}
extendedGroupSearchFilter = extendedGroupSearchFilter + customFilter;
}
-
- DateFormat dateFormat = new SimpleDateFormat("yyyyMMddhhmmss");
+
extendedAllGroupsSearchFilter = "(&" + extendedGroupSearchFilter + "(|(uSNChanged>=" + deltaSyncGroupTime + ")(modifyTimestamp>=" + deltaSyncGroupTimeStamp + "Z)))";
-
+
LOG.info("extendedAllGroupsSearchFilter = " + extendedAllGroupsSearchFilter);
- long highestdeltaSyncGroupTime = deltaSyncGroupTime;
for (int ou=0; ou<groupSearchBase.length; ou++) {
byte[] cookie = null;
int counter = 0;
@@ -646,7 +663,7 @@ public class LdapDeltaUserGroupBuilder extends AbstractUserGroupSource {
timeStampAttr = groupEntry.getAttributes().get("modifytimestamp");
if (timeStampAttr != null) {
String timeStampVal = (String) timeStampAttr.get();
- Date parseDate = dateFormat.parse(timeStampVal);
+ Date parseDate = dateFormat.parse(timeStampVal);
long currentDeltaSyncTime = parseDate.getTime();
LOG.info("timeStampVal = " + timeStampVal + "and currentDeltaSyncTime = " + currentDeltaSyncTime);
if (currentDeltaSyncTime > highestdeltaSyncGroupTime) {
@@ -661,7 +678,7 @@ public class LdapDeltaUserGroupBuilder extends AbstractUserGroupSource {
LOG.info("No members available for " + gName);
continue;
}
-
+
NamingEnumeration<?> userEnum = groupMemberAttr.getAll();
while (userEnum.hasMore()) {
String originalUserFullName = (String) userEnum.next();
@@ -687,6 +704,7 @@ public class LdapDeltaUserGroupBuilder extends AbstractUserGroupSource {
} else {
groupUserTable.put(gName, originalUserFullName, originalUserFullName);
}
+ groupNameMap.put(groupEntry.getNameInNamespace().toLowerCase(), gName);
}
LOG.info("No. of members in the group " + gName + " = " + userCount);
}
@@ -719,17 +737,11 @@ public class LdapDeltaUserGroupBuilder extends AbstractUserGroupSource {
LOG.info("LdapDeltaUserGroupBuilder.getGroups() completed with group count: "
+ counter);
} catch (Exception t) {
- LOG.error("LdapDeltaUserGroupBuilder.getGroups() failed with exception: " + t);
+ LOG.error("LdapDeltaUserGroupBuilder.getGroups() failed with exception: " + t);
LOG.info("LdapDeltaUserGroupBuilder.getGroups() group count: "
+ counter);
}
}
- if (deltaSyncGroupTime < highestdeltaSyncGroupTime) {
- // Incrementing highestdeltaSyncGroupTime (for AD) in order to avoid search record repetition for next sync cycle.
- deltaSyncGroupTime = highestdeltaSyncGroupTime+1;
- // Incrementing the highest timestamp value (for OpenLdap) with 1min in order to avoid search record repetition for next sync cycle.
- deltaSyncGroupTimeStamp = dateFormat.format(new Date(highestdeltaSyncGroupTime + 60000l));
- }
} finally {
if (groupSearchResultEnum != null) {
@@ -737,9 +749,22 @@ public class LdapDeltaUserGroupBuilder extends AbstractUserGroupSource {
}
closeLdapContext();
}
+
+ if (groupHierarchyLevels > 0) {
+ if (deltaSyncGroupTime > 0) {
+ goUpGroupHierarchyLdap(groupNameMap.keySet(), groupHierarchyLevels-1);
+ }
+ }
+
+ if (deltaSyncGroupTime < highestdeltaSyncGroupTime) {
+ // Incrementing highestdeltaSyncGroupTime (for AD) in order to avoid search record repetition for next sync cycle.
+ deltaSyncGroupTime = highestdeltaSyncGroupTime+1;
+ // Incrementing the highest timestamp value (for OpenLdap) with 1min in order to avoid search record repetition for next sync cycle.
+ deltaSyncGroupTimeStamp = dateFormat.format(new Date(highestdeltaSyncGroupTime + 60000l));
+ }
}
-
+
private static String getShortGroupName(String longGroupName) throws InvalidNameException {
if (longGroupName == null) {
return null;
@@ -755,7 +780,7 @@ public class LdapDeltaUserGroupBuilder extends AbstractUserGroupSource {
LOG.info("longGroupName: " + longGroupName + ", groupName: " + groupName);
return groupName;
}
-
+
private static String getShortUserName(String longUserName) throws InvalidNameException {
if (longUserName == null) {
return null;
@@ -771,7 +796,7 @@ public class LdapDeltaUserGroupBuilder extends AbstractUserGroupSource {
LOG.info("longUserName: " + longUserName + ", userName: " + userName);
return userName;
}
-
+
private String userNameTransform(String userName) {
//String userNameTransform = userName;
if (userNameCaseConversionFlag) {
@@ -789,7 +814,7 @@ public class LdapDeltaUserGroupBuilder extends AbstractUserGroupSource {
return userName;
}
-
+
private String groupNameTransform(String groupName) {
//String userNameTransform = userName;
if (groupNameCaseConversionFlag) {
@@ -807,37 +832,167 @@ public class LdapDeltaUserGroupBuilder extends AbstractUserGroupSource {
return groupName;
}
-
-}
-/*class UserInfo {
- private String userName;
- private String userFullName;
- private Set<String> groupList;
-
- public UserInfo(String userName, String userFullName) {
- this.userName = userName;
- this.userFullName = userFullName;
- this.groupList = new HashSet<String>();
- }
-
- public void updateUserName(String userName) {
- this.userName = userName;
- }
-
- public String getUserName() {
- return userName;
- }
- public String getUserFullName() {
- return userFullName;
- }
- public void addGroups(Set<String> groups) {
- groupList.addAll(groups);
- }
- public void addGroup(String group) {
- groupList.add(group);
+ private void goUpGroupHierarchy(Set<String> groups, int groupHierarchyLevels, String groupSName) throws InvalidNameException {
+ if (groupHierarchyLevels <= 0 || groups.isEmpty()) {
+ return;
+ }
+ LOG.info("nextLevelGroups = " + groups + " for group = " + groupSName);
+ Set<String> nextLevelGroups;
+
+ for (String group : groups) {
+ String groupFullName = groupNameMap.getKey(group).toString();
+
+ // Add all members of sub group to the parent groups if the member is not a group in turn
+ Set<String> allMembers = groupUserTable.row(groupSName).keySet();
+ for(String member : allMembers) {
+ String memberName = getShortGroupName(member);
+ if (!groupUserTable.containsRow(memberName)) { //Check if the member of a group is in turn a group
+ LOG.info("Adding " + member + " to " + group);
+ String userSName = groupUserTable.get(groupSName, member);
+ LOG.info("Short name of " + member + " = " + userSName);
+ if (userSName != null) {
+ groupUserTable.put(group, member, userSName); //Add users from the nested group to parent group
+ }
+ }
+ }
+ nextLevelGroups = groupUserTable.column(groupFullName).keySet();
+ goUpGroupHierarchy(nextLevelGroups, groupHierarchyLevels - 1, group);
+ }
}
- public List<String> getGroups() {
- return (new ArrayList<String>(groupList));
+
+ private void goUpGroupHierarchyLdap(Set<String> groupDNs, int groupHierarchyLevels) throws Throwable {
+ if (groupHierarchyLevels <= 0 || groupDNs.isEmpty()) {
+ return;
+ }
+ Set<String> nextLevelGroups = new HashSet<String>();
+
+ NamingEnumeration<SearchResult> groupSearchResultEnum = null;
+ try {
+ createLdapContext();
+ int total;
+ // Activate paged results
+ if (pagedResultsEnabled) {
+ ldapContext.setRequestControls(new Control[]{
+ new PagedResultsControl(pagedResultsSize, Control.NONCRITICAL) });
+ }
+ String groupFilter = "(&(objectclass=" + groupObjectClass + ")";
+ if (groupSearchFilter != null && !groupSearchFilter.trim().isEmpty()) {
+ String customFilter = groupSearchFilter.trim();
+ if (!customFilter.startsWith("(")) {
+ customFilter = "(" + customFilter + ")";
+ }
+ groupFilter += customFilter + "(|";
+ }
+ StringBuilder filter = new StringBuilder();
+
+ for (String groupDN : groupDNs) {
+ filter.append("(").append(groupMemberAttributeName).append("=")
+ .append(groupDN).append(")");
+ }
+ filter.append("))");
+ groupFilter += filter;
+
+ LOG.info("extendedAllGroupsSearchFilter = " + groupFilter);
+ for (int ou=0; ou<groupSearchBase.length; ou++) {
+ byte[] cookie = null;
+ int counter = 0;
+ try {
+ do {
+ groupSearchResultEnum = ldapContext
+ .search(groupSearchBase[ou], groupFilter,
+ groupSearchControls);
+ while (groupSearchResultEnum.hasMore()) {
+ final SearchResult groupEntry = groupSearchResultEnum.next();
+ if (groupEntry == null) {
+ if (LOG.isInfoEnabled()) {
+ LOG.info("groupEntry null, skipping sync for the entry");
+ }
+ continue;
+ }
+ counter++;
+ Attribute groupNameAttr = groupEntry.getAttributes().get(groupNameAttribute);
+ if (groupNameAttr == null) {
+ if (LOG.isInfoEnabled()) {
+ LOG.info(groupNameAttribute + " empty for entry " + groupEntry.getNameInNamespace() +
+ ", skipping sync");
+ }
+ continue;
+ }
+ nextLevelGroups.add(groupEntry.getNameInNamespace());
+ String gName = (String) groupNameAttr.get();
+
+ Attribute groupMemberAttr = groupEntry.getAttributes().get(groupMemberAttributeName);
+ int userCount = 0;
+ if (groupMemberAttr == null || groupMemberAttr.size() <= 0) {
+ LOG.info("No members available for " + gName);
+ continue;
+ }
+
+ NamingEnumeration<?> userEnum = groupMemberAttr.getAll();
+ while (userEnum.hasMore()) {
+ String originalUserFullName = (String) userEnum.next();
+ if (originalUserFullName == null || originalUserFullName.trim().isEmpty()) {
+ continue;
+ }
+ userCount++;
+ originalUserFullName = originalUserFullName.toLowerCase();
+ if (userNameMap.get(originalUserFullName) != null) {
+ groupUserTable.put(gName, originalUserFullName, userNameMap.get(originalUserFullName));
+ } else {
+ groupUserTable.put(gName, originalUserFullName, originalUserFullName);
+ }
+
+ }
+ LOG.info("No. of members in the group " + gName + " = " + userCount);
+ }
+ // Examine the paged results control response
+ Control[] controls = ldapContext.getResponseControls();
+ if (controls != null) {
+ for (int i = 0; i < controls.length; i++) {
+ if (controls[i] instanceof PagedResultsResponseControl) {
+ PagedResultsResponseControl prrc =
+ (PagedResultsResponseControl)controls[i];
+ total = prrc.getResultSize();
+ if (total != 0) {
+ LOG.debug("END-OF-PAGE total : " + total);
+ } else {
+ LOG.debug("END-OF-PAGE total : unknown");
+ }
+ cookie = prrc.getCookie();
+ }
+ }
+ } else {
+ LOG.debug("No controls were sent from the server");
+ }
+ // Re-activate paged results
+ if (pagedResultsEnabled) {
+ ldapContext.setRequestControls(new Control[]{
+ new PagedResultsControl(pagedResultsSize, cookie, Control.CRITICAL) });
+ }
+ } while (cookie != null);
+ LOG.info("LdapDeltaUserGroupBuilder.goUpGroupHierarchyLdap() completed with group count: "
+ + counter);
+ } catch (RuntimeException re) {
+ LOG.error("LdapDeltaUserGroupBuilder.goUpGroupHierarchyLdap() failed with runtime exception: ", re);
+ throw re;
+ } catch (Exception t) {
+ LOG.error("LdapDeltaUserGroupBuilder.goUpGroupHierarchyLdap() failed with exception: ", t);
+ LOG.info("LdapDeltaUserGroupBuilder.goUpGroupHierarchyLdap() group count: "
+ + counter);
+ }
+ }
+
+ } catch (RuntimeException re) {
+ LOG.error("LdapDeltaUserGroupBuilder.goUpGroupHierarchyLdap() failed with exception: ", re);
+ throw re;
+ } finally {
+ if (groupSearchResultEnum != null) {
+ groupSearchResultEnum.close();
+ }
+ closeLdapContext();
+ }
+ goUpGroupHierarchyLdap(nextLevelGroups, groupHierarchyLevels-1);
}
-}*/
+}
+
http://git-wip-us.apache.org/repos/asf/ranger/blob/f780aba3/ugsync/src/main/java/org/apache/ranger/ldapusersync/process/LdapUserGroupBuilder.java
----------------------------------------------------------------------
diff --git a/ugsync/src/main/java/org/apache/ranger/ldapusersync/process/LdapUserGroupBuilder.java b/ugsync/src/main/java/org/apache/ranger/ldapusersync/process/LdapUserGroupBuilder.java
index 4e9f87a..9999988 100644
--- a/ugsync/src/main/java/org/apache/ranger/ldapusersync/process/LdapUserGroupBuilder.java
+++ b/ugsync/src/main/java/org/apache/ranger/ldapusersync/process/LdapUserGroupBuilder.java
@@ -87,6 +87,7 @@ public class LdapUserGroupBuilder extends AbstractUserGroupSource {
private SearchControls groupSearchControls;
private String groupMemberAttributeName;
private String groupNameAttribute;
+ private int groupHierarchyLevels;
private LdapContext ldapContext;
private StartTlsResponse tls;
@@ -99,6 +100,7 @@ public class LdapUserGroupBuilder extends AbstractUserGroupSource {
private boolean groupUserMapSyncEnabled;
private Map<String, UserInfo> userGroupMap;
+ //private Set<String> firstGroupDNs;
public static void main(String[] args) throws Throwable {
LdapUserGroupBuilder ugBuilder = new LdapUserGroupBuilder();
@@ -131,7 +133,7 @@ public class LdapUserGroupBuilder extends AbstractUserGroupSource {
}
@Override
- public void init() throws Throwable{
+ public void init() throws Throwable{
setConfig();
}
@@ -205,7 +207,7 @@ public class LdapUserGroupBuilder extends AbstractUserGroupSource {
userSearchControls = new SearchControls();
userSearchControls.setSearchScope(userSearchScope);
userSearchControls.setReturningAttributes(userSearchAttributes.toArray(
- new String[userSearchAttributes.size()]));
+ new String[userSearchAttributes.size()]));
pagedResultsEnabled = config.isPagedResultsEnabled();
pagedResultsSize = config.getPagedResultsSize();
@@ -216,6 +218,7 @@ public class LdapUserGroupBuilder extends AbstractUserGroupSource {
groupSearchFilter = config.getGroupSearchFilter();
groupMemberAttributeName = config.getUserGroupMemberAttributeName();
groupNameAttribute = config.getGroupNameAttribute();
+ groupHierarchyLevels = config.getGroupHierarchyLevels();
extendedGroupSearchFilter = "(objectclass=" + groupObjectClass + ")";
if (groupSearchFilter != null && !groupSearchFilter.trim().isEmpty()) {
@@ -296,20 +299,30 @@ public class LdapUserGroupBuilder extends AbstractUserGroupSource {
public void updateSink(UserGroupSink sink) throws Throwable {
LOG.info("LDAPUserGroupBuilder updateSink started");
userGroupMap = new HashMap<String, UserInfo>();
+
if (!groupSearchFirstEnabled) {
LOG.info("Performing user search first");
getUsers(sink);
-
LOG.debug("Total No. of users saved = " + userGroupMap.size());
- //Iterator<UserInfo> userInfoIterator = userGroupMap.
+ if (!groupSearchEnabled && groupHierarchyLevels > 0) {
+ getRootDN();
+ }
+ //Iterator<UserInfo> userInfoIterator = userGroupMap.
for (UserInfo userInfo : userGroupMap.values()) {
String userName = userInfo.getUserName();
if (groupSearchEnabled) {
// Perform group search
LOG.info("groupSearch is enabled, would search for groups and compute memberships");
+ //firstGroupDNs = new HashSet<String>();
getGroups(sink, userInfo);
}
+ if (groupHierarchyLevels > 0) {
+ LOG.debug("Going through group hierarchy for nested group evaluation");
+ goUpGroupHierarchyLdap(userInfo.getGroupDNs(), groupHierarchyLevels - 1, userInfo);
+ LOG.debug("Completed group hierarchy computation");
+ }
List<String> groupList = userInfo.getGroups();
+ LOG.debug("updateSink(): group list for " + userName + " = " + groupList);
if (userNameCaseConversionFlag) {
if (userNameLowerCaseFlag) {
userName = userName.toLowerCase();
@@ -334,37 +347,41 @@ public class LdapUserGroupBuilder extends AbstractUserGroupSource {
} else {
LOG.info("Performing Group search first");
getGroups(sink, null);
- if (userSearchEnabled) {
- LOG.info("User search is enabled and hence computing user membership.");
- getUsers(sink);
- } else {
- LOG.info("User search is disabled and hence using the group member attribute for username.");
- // Go through the userInfo map and update ranger admin.
- for (UserInfo userInfo : userGroupMap.values()) {
- String userName = getShortUserName(userInfo.getUserFullName());
- List<String> groupList = userInfo.getGroups();
- if (userNameCaseConversionFlag) {
- if (userNameLowerCaseFlag) {
- userName = userName.toLowerCase();
- }
- else {
- userName = userName.toUpperCase();
- }
- }
-
- if (userNameRegExInst != null) {
- userName = userNameRegExInst.transform(userName);
- }
-
- try {
- sink.addOrUpdateUser(userName, groupList);
- } catch (Throwable t) {
- LOG.error("sink.addOrUpdateUser failed with exception: " + t.getMessage()
- + ", for user: " + userName
- + ", groups: " + groupList);
- }
- }
- }
+ // Go through the userInfo map and update ranger admin.
+ for (UserInfo userInfo : userGroupMap.values()) {
+ String userName = getShortUserName(userInfo.getUserFullName());
+ if (groupHierarchyLevels > 0) {
+ //System.out.println("Going through group hierarchy for nested group evaluation");
+ goUpGroupHierarchyLdap(userInfo.getGroupDNs(), groupHierarchyLevels - 1, userInfo);
+ //System.out.println("Completed group hierarchy computation");
+ }
+ if (userSearchEnabled) {
+ LOG.info("User search is enabled and hence computing user membership.");
+ getUsers(sink);
+ } else {
+ LOG.info("User search is disabled and hence using the group member attribute for username" + userName);
+ List<String> groupList = userInfo.getGroups();
+ if (userNameCaseConversionFlag) {
+ if (userNameLowerCaseFlag) {
+ userName = userName.toLowerCase();
+ } else {
+ userName = userName.toUpperCase();
+ }
+ }
+
+ if (userNameRegExInst != null) {
+ userName = userNameRegExInst.transform(userName);
+ }
+
+ try {
+ sink.addOrUpdateUser(userName, groupList);
+ } catch (Throwable t) {
+ LOG.error("sink.addOrUpdateUser failed with exception: " + t.getMessage()
+ + ", for user: " + userName
+ + ", groups: " + groupList);
+ }
+ }
+ }
}
}
@@ -442,8 +459,10 @@ public class LdapUserGroupBuilder extends AbstractUserGroupSource {
if (userGroupfAttribute != null) {
NamingEnumeration<?> groupEnum = userGroupfAttribute.getAll();
while (groupEnum.hasMore()) {
- String gName = getShortGroupName((String) groupEnum
- .next());
+ String groupDN = (String) groupEnum.next();
+ LOG.debug("Adding " + groupDN + " to " + userName);
+ userInfo.addGroupDN(groupDN);
+ String gName = getShortGroupName(groupDN);
if (groupNameCaseConversionFlag) {
if (groupNameLowerCaseFlag) {
gName = gName.toLowerCase();
@@ -498,7 +517,7 @@ public class LdapUserGroupBuilder extends AbstractUserGroupSource {
// then update user name in the userInfo map with the value from the search result
// and update ranger admin.
String userFullName = (userEntry.getNameInNamespace()).toLowerCase();
- LOG.debug("Chekcing if the user " + userFullName + " is part of the retrieved groups");
+ LOG.debug("Checking if the user " + userFullName + " is part of the retrieved groups");
userInfo = userGroupMap.get(userFullName);
if (userInfo == null) {
@@ -508,27 +527,27 @@ public class LdapUserGroupBuilder extends AbstractUserGroupSource {
counter++;
LOG.info("Updating username for " + userFullName + " with " + userName);
userInfo.updateUserName(userName);
- List<String> groupList = userInfo.getGroups();
- if (userNameCaseConversionFlag) {
- if (userNameLowerCaseFlag) {
- userName = userName.toLowerCase();
- }
- else {
- userName = userName.toUpperCase();
- }
- }
-
- if (userNameRegExInst != null) {
- userName = userNameRegExInst.transform(userName);
- }
-
- try {
- sink.addOrUpdateUser(userName, groupList);
- } catch (Throwable t) {
- LOG.error("sink.addOrUpdateUser failed with exception: " + t.getMessage()
- + ", for user: " + userName
- + ", groups: " + groupList);
- }
+ List<String> groupList = userInfo.getGroups();
+ if (userNameCaseConversionFlag) {
+ if (userNameLowerCaseFlag) {
+ userName = userName.toLowerCase();
+ }
+ else {
+ userName = userName.toUpperCase();
+ }
+ }
+
+ if (userNameRegExInst != null) {
+ userName = userNameRegExInst.transform(userName);
+ }
+
+ try {
+ sink.addOrUpdateUser(userName, groupList);
+ } catch (Throwable t) {
+ LOG.error("sink.addOrUpdateUser failed with exception: " + t.getMessage()
+ + ", for user: " + userName
+ + ", groups: " + groupList);
+ }
}
}
@@ -581,11 +600,12 @@ public class LdapUserGroupBuilder extends AbstractUserGroupSource {
}
private void getGroups(UserGroupSink sink, UserInfo userInfo) throws Throwable {
+ //LOG.debug("getGroups(): for user " + userInfo.getUserName());
NamingEnumeration<SearchResult> groupSearchResultEnum = null;
try {
createLdapContext();
int total;
- // Activate paged results
+ // Activate paged results
if (pagedResultsEnabled) {
ldapContext.setRequestControls(new Control[]{
new PagedResultsControl(pagedResultsSize, Control.NONCRITICAL) });
@@ -617,6 +637,7 @@ public class LdapUserGroupBuilder extends AbstractUserGroupSource {
if (groupEntry != null) {
counter++;
Attribute groupNameAttr = groupEntry.getAttributes().get(groupNameAttribute);
+ //System.out.println("getGroups(): Going through all groups");
if (groupNameAttr == null) {
if (LOG.isInfoEnabled()) {
LOG.info(groupNameAttribute + " empty for entry " + groupEntry.getNameInNamespace() +
@@ -624,7 +645,9 @@ public class LdapUserGroupBuilder extends AbstractUserGroupSource {
}
continue;
}
- String gName = (String) groupNameAttr.get();
+ String groupDN = groupEntry.getNameInNamespace();
+ //System.out.println("getGroups(): groupDN = " + groupDN);
+ String gName = (String) groupNameAttr.get();
if (groupNameCaseConversionFlag) {
if (groupNameLowerCaseFlag) {
gName = gName.toLowerCase();
@@ -638,9 +661,10 @@ public class LdapUserGroupBuilder extends AbstractUserGroupSource {
if (!groupSearchFirstEnabled) {
//computedGroups.add(gName);
if (LOG.isInfoEnabled()) {
- LOG.info("computed groups for user: " + userInfo.getUserName() +", groups: " + gName);
+ LOG.info("computed groups for user: " + userInfo.getUserName() + ", groups: " + gName);
}
- userInfo.addGroup(gName);
+ userInfo.addGroupDN(groupDN);
+ userInfo.addGroup(gName);
} else {
// If group based search is enabled, then
// update the group name to ranger admin
@@ -666,9 +690,10 @@ public class LdapUserGroupBuilder extends AbstractUserGroupSource {
userGroupMap.put(userFullName, userInfo);
} else {
userInfo = userGroupMap.get(userFullName);
- }
- LOG.info("Adding " + gName + " to user " + userInfo.getUserFullName());
- userInfo.addGroup(gName);
+ }
+ LOG.info("Adding " + gName + " to user " + userInfo.getUserFullName());
+ userInfo.addGroup(gName);
+ userInfo.addGroupDN(groupDN);
}
LOG.info("No. of members in the group " + gName + " = " + userCount);
}
@@ -750,17 +775,172 @@ public class LdapUserGroupBuilder extends AbstractUserGroupSource {
return userName;
}
+ private void goUpGroupHierarchyLdap(Set<String> groupDNs, int groupHierarchyLevels, UserInfo userInfo) throws Throwable {
+ LOG.debug("goUpGroupHierarchyLdap(): Incoming groups " + groupDNs);
+ if (groupHierarchyLevels <= 0 || groupDNs.isEmpty()) {
+ return;
+ }
+ Set<String> nextLevelGroups = new HashSet<String>();
+
+ NamingEnumeration<SearchResult> groupSearchResultEnum = null;
+ try {
+ createLdapContext();
+ int total;
+ // Activate paged results
+ if (pagedResultsEnabled) {
+ ldapContext.setRequestControls(new Control[]{
+ new PagedResultsControl(pagedResultsSize, Control.NONCRITICAL) });
+ }
+ String groupFilter = "(&(objectclass=" + groupObjectClass + ")";
+ if (groupSearchFilter != null && !groupSearchFilter.trim().isEmpty()) {
+ String customFilter = groupSearchFilter.trim();
+ if (!customFilter.startsWith("(")) {
+ customFilter = "(" + customFilter + ")";
+ }
+ groupFilter += customFilter + "(|";
+ }
+ StringBuilder filter = new StringBuilder();
+
+ for (String groupDN : groupDNs) {
+ filter.append("(").append(groupMemberAttributeName).append("=")
+ .append(groupDN).append(")");
+ }
+ filter.append("))");
+ groupFilter += filter;
+
+ LOG.debug("extendedAllGroupsSearchFilter = " + groupFilter);
+ for (int ou=0; ou<groupSearchBase.length; ou++) {
+ byte[] cookie = null;
+ int counter = 0;
+ try {
+ do {
+ groupSearchResultEnum = ldapContext
+ .search(groupSearchBase[ou], groupFilter,
+ groupSearchControls);
+ //System.out.println("goUpGroupHierarchyLdap(): Going through the sub groups");
+ while (groupSearchResultEnum.hasMore()) {
+ final SearchResult groupEntry = groupSearchResultEnum.next();
+ if (groupEntry == null) {
+ if (LOG.isInfoEnabled()) {
+ LOG.info("groupEntry null, skipping sync for the entry");
+ }
+ continue;
+ }
+ counter++;
+ Attribute groupNameAttr = groupEntry.getAttributes().get(groupNameAttribute);
+ if (groupNameAttr == null) {
+ if (LOG.isInfoEnabled()) {
+ LOG.info(groupNameAttribute + " empty for entry " + groupEntry.getNameInNamespace() +
+ ", skipping sync");
+ }
+ continue;
+ }
+ String groupDN = groupEntry.getNameInNamespace();
+ //System.out.println("goUpGroupHierarchyLdap(): next Level Group DN = " + groupDN);
+ nextLevelGroups.add(groupDN);
+ String gName = (String) groupNameAttr.get();
+ if (groupNameCaseConversionFlag) {
+ if (groupNameLowerCaseFlag) {
+ gName = gName.toLowerCase();
+ } else {
+ gName = gName.toUpperCase();
+ }
+ }
+ if (groupNameRegExInst != null) {
+ gName = groupNameRegExInst.transform(gName);
+ }
+ userInfo.addGroup(gName);
+ }
+ // Examine the paged results control response
+ Control[] controls = ldapContext.getResponseControls();
+ if (controls != null) {
+ for (int i = 0; i < controls.length; i++) {
+ if (controls[i] instanceof PagedResultsResponseControl) {
+ PagedResultsResponseControl prrc =
+ (PagedResultsResponseControl)controls[i];
+ total = prrc.getResultSize();
+ if (total != 0) {
+ LOG.debug("END-OF-PAGE total : " + total);
+ } else {
+ LOG.debug("END-OF-PAGE total : unknown");
+ }
+ cookie = prrc.getCookie();
+ }
+ }
+ } else {
+ LOG.debug("No controls were sent from the server");
+ }
+ // Re-activate paged results
+ if (pagedResultsEnabled) {
+ ldapContext.setRequestControls(new Control[]{
+ new PagedResultsControl(PAGE_SIZE, cookie, Control.CRITICAL) });
+ }
+ } while (cookie != null);
+ LOG.info("LdapUserGroupBuilder.goUpGroupHierarchyLdap() completed with group count: "
+ + counter);
+ } catch (RuntimeException re) {
+ LOG.error("LdapUserGroupBuilder.goUpGroupHierarchyLdap() failed with runtime exception: ", re);
+ throw re;
+ } catch (Exception t) {
+ LOG.error("LdapUserGroupBuilder.goUpGroupHierarchyLdap() failed with exception: ", t);
+ LOG.info("LdapUserGroupBuilder.goUpGroupHierarchyLdap() group count: "
+ + counter);
+ }
+ }
+
+ } catch (RuntimeException re) {
+ LOG.error("LdapUserGroupBuilder.goUpGroupHierarchyLdap() failed with exception: ", re);
+ throw re;
+ } finally {
+ if (groupSearchResultEnum != null) {
+ groupSearchResultEnum.close();
+ }
+ closeLdapContext();
+ }
+ goUpGroupHierarchyLdap(nextLevelGroups, groupHierarchyLevels - 1, userInfo);
+ }
+
+ private void getRootDN() throws Throwable {
+ NamingEnumeration groupSearchResultEnum = null;
+ SearchControls sc1 = new SearchControls();
+ sc1.setSearchScope(SearchControls.OBJECT_SCOPE);
+ sc1.setReturningAttributes(new String[]{"namingContexts"});
+ try {
+ createLdapContext();
+ groupSearchResultEnum = ldapContext
+ .search("", "objectclass=*", sc1);
+ //System.out.println("goUpGroupHierarchyLdap(): Going through the sub groups");
+ while (groupSearchResultEnum.hasMore()) {
+ SearchResult result1 = (SearchResult) groupSearchResultEnum.next();
+
+ Attributes attrs = result1.getAttributes();
+ Attribute attr = attrs.get("namingContexts");
+ LOG.debug("namingContexts = " + attr);
+ groupSearchBase = new String[] {attr.get(0).toString()};
+ LOG.info("RootDN = " + Arrays.toString(groupSearchBase));
+ }
+ } catch (RuntimeException re) {
+ throw re;
+ } finally {
+ if (groupSearchResultEnum != null) {
+ groupSearchResultEnum.close();
+ }
+ closeLdapContext();
+ }
+ }
}
class UserInfo {
private String userName;
private String userFullName;
private Set<String> groupList;
+ private Set<String> groupDNList;
public UserInfo(String userName, String userFullName) {
this.userName = userName;
this.userFullName = userFullName;
this.groupList = new HashSet<String>();
+ this.groupDNList = new HashSet<String>();
}
public void updateUserName(String userName) {
@@ -782,4 +962,14 @@ class UserInfo {
public List<String> getGroups() {
return (new ArrayList<String>(groupList));
}
+
+ public void addGroupDNs(Set<String> groupDNs) {
+ groupDNList.addAll(groupDNs);
+ }
+ public void addGroupDN(String groupDN) {
+ groupDNList.add(groupDN);
+ }
+ public Set<String> getGroupDNs() {
+ return (groupDNList);
+ }
}
http://git-wip-us.apache.org/repos/asf/ranger/blob/f780aba3/ugsync/src/main/java/org/apache/ranger/unixusersync/config/UserGroupSyncConfig.java
----------------------------------------------------------------------
diff --git a/ugsync/src/main/java/org/apache/ranger/unixusersync/config/UserGroupSyncConfig.java b/ugsync/src/main/java/org/apache/ranger/unixusersync/config/UserGroupSyncConfig.java
index 1564760..d150cd4 100644
--- a/ugsync/src/main/java/org/apache/ranger/unixusersync/config/UserGroupSyncConfig.java
+++ b/ugsync/src/main/java/org/apache/ranger/unixusersync/config/UserGroupSyncConfig.java
@@ -200,6 +200,9 @@ public class UserGroupSyncConfig {
private static final String LGSYNC_GROUP_MEMBER_ATTRIBUTE_NAME = "ranger.usersync.group.memberattributename";
private static final String DEFAULT_LGSYNC_GROUP_MEMBER_ATTRIBUTE_NAME = "member";
+ private static final String LGSYNC_GROUP_HIERARCHY_LEVELS = "ranger.usersync.ldap.grouphierarchylevels";
+ private static final int DEFAULT_LGSYNC_GROUP_HIERARCHY_LEVELS = 0;
+
private static final String UGSYNC_UPDATE_MILLIS_MIN = "ranger.usersync.unix.updatemillismin";
private final static long DEFAULT_UGSYNC_UPDATE_MILLIS_MIN = 1 * 60 * 1000; // ms
@@ -864,6 +867,20 @@ public class UserGroupSyncConfig {
return val;
}
+ public int getGroupHierarchyLevels() {
+ int groupHierarchyLevels;
+ String val = prop.getProperty(LGSYNC_GROUP_HIERARCHY_LEVELS);
+ if(val == null || val.trim().isEmpty()) {
+ groupHierarchyLevels = DEFAULT_LGSYNC_GROUP_HIERARCHY_LEVELS;
+ } else {
+ groupHierarchyLevels = Integer.parseInt(val);
+ }
+ if (groupHierarchyLevels < 0) {
+ groupHierarchyLevels = DEFAULT_LGSYNC_GROUP_HIERARCHY_LEVELS;
+ }
+ return groupHierarchyLevels;
+ }
+
public String getProperty(String aPropertyName) {
return prop.getProperty(aPropertyName);
}
@@ -1065,14 +1082,19 @@ public class UserGroupSyncConfig {
}
/* Used only for unit testing */
- public void setDeltaSync(boolean deltaSyncEnabled) {
- prop.setProperty(LGSYNC_LDAP_DELTASYNC_ENABLED, String.valueOf(deltaSyncEnabled));
- }
-
- /* Used only for unit testing */
- public void setUserNameAttribute(String userNameAttr) {
- prop.setProperty(LGSYNC_USER_NAME_ATTRIBUTE, userNameAttr);
- }
+ public void setDeltaSync(boolean deltaSyncEnabled) {
+ prop.setProperty(LGSYNC_LDAP_DELTASYNC_ENABLED, String.valueOf(deltaSyncEnabled));
+ }
+
+ /* Used only for unit testing */
+ public void setUserNameAttribute(String userNameAttr) {
+ prop.setProperty(LGSYNC_USER_NAME_ATTRIBUTE, userNameAttr);
+ }
+
+ /* Used only for unit testing */
+ public void setGroupHierarchyLevel(int groupHierarchyLevel) {
+ prop.setProperty(LGSYNC_GROUP_HIERARCHY_LEVELS, String.valueOf(groupHierarchyLevel));
+ }
public String getGroupRoleRules() {
if(prop != null && prop.containsKey(GROUP_BASED_ROLE_ASSIGNMENT_RULES)) {
http://git-wip-us.apache.org/repos/asf/ranger/blob/f780aba3/ugsync/src/test/java/org/apache/ranger/usergroupsync/TestLdapUserGroup.java
----------------------------------------------------------------------
diff --git a/ugsync/src/test/java/org/apache/ranger/usergroupsync/TestLdapUserGroup.java b/ugsync/src/test/java/org/apache/ranger/usergroupsync/TestLdapUserGroup.java
index 6ebc311..6393b3d 100644
--- a/ugsync/src/test/java/org/apache/ranger/usergroupsync/TestLdapUserGroup.java
+++ b/ugsync/src/test/java/org/apache/ranger/usergroupsync/TestLdapUserGroup.java
@@ -104,6 +104,7 @@ public class TestLdapUserGroup extends AbstractLdapTestUnit{
config.setGroupSearchEnabled(false);
config.setPagedResultsEnabled(true);
config.setGroupSearchFirstEnabled(false);
+ //config.setGroupHierarchyLevel(0);
ldapBuilder.init();
PolicyMgrUserGroupBuilderTest sink = new PolicyMgrUserGroupBuilderTest();
sink.init();
@@ -123,6 +124,7 @@ public class TestLdapUserGroup extends AbstractLdapTestUnit{
config.setGroupSearchEnabled(false);
config.setPagedResultsEnabled(false);
config.setGroupSearchFirstEnabled(false);
+ //config.setGroupHierarchyLevel(0);
ldapBuilder.init();
PolicyMgrUserGroupBuilderTest sink = new PolicyMgrUserGroupBuilderTest();
sink.init();
@@ -318,11 +320,12 @@ public class TestLdapUserGroup extends AbstractLdapTestUnit{
config.setGroupObjectClass("groupOfNames");
config.setGroupSearchEnabled(true);
config.setGroupSearchFirstEnabled(true);
+ config.setUserSearchEnabled(false);
ldapBuilder.init();
PolicyMgrUserGroupBuilderTest sink = new PolicyMgrUserGroupBuilderTest();
sink.init();
ldapBuilder.updateSink(sink);
- assertEquals(2, sink.getTotalUsers());
+ assertEquals(3, sink.getTotalUsers());
assertEquals(2, sink.getTotalGroups());
}
@@ -444,7 +447,7 @@ public class TestLdapUserGroup extends AbstractLdapTestUnit{
PolicyMgrUserGroupBuilderTest sink = new PolicyMgrUserGroupBuilderTest();
sink.init();
ldapBuilder.updateSink(sink);
- assertEquals(2, sink.getTotalUsers());
+ assertEquals(3, sink.getTotalUsers());
assertEquals(2, sink.getTotalGroups());
}
@@ -561,7 +564,7 @@ public class TestLdapUserGroup extends AbstractLdapTestUnit{
PolicyMgrUserGroupBuilderTest sink = new PolicyMgrUserGroupBuilderTest();
sink.init();
ldapBuilder.updateSink(sink);
- assertEquals(1, sink.getTotalUsers());
+ assertEquals(2, sink.getTotalUsers());
assertEquals(1, sink.getTotalGroups());
}
@@ -694,7 +697,7 @@ public class TestLdapUserGroup extends AbstractLdapTestUnit{
LdapPolicyMgrUserGroupBuilderTest sink = new LdapPolicyMgrUserGroupBuilderTest();
sink.init();
ldapBuilder.updateSink(sink);
- assertEquals(2, sink.getTotalUsers());
+ assertEquals(3, sink.getTotalUsers());
assertEquals(2, sink.getTotalGroups());
}
http://git-wip-us.apache.org/repos/asf/ranger/blob/f780aba3/ugsync/src/test/resources/ADSchema.ldif
----------------------------------------------------------------------
diff --git a/ugsync/src/test/resources/ADSchema.ldif b/ugsync/src/test/resources/ADSchema.ldif
index a45a2fb..1a343ed 100644
--- a/ugsync/src/test/resources/ADSchema.ldif
+++ b/ugsync/src/test/resources/ADSchema.ldif
@@ -2362,6 +2362,7 @@ objectClass: top
objectClass: groupOfNames
cn: Group10
member: CN=User1000,CN=Users,DC=ranger,DC=qe,DC=hortonworks,DC=com
+member: CN=Group19,OU=Groups,DC=ranger,DC=qe,DC=hortonworks,DC=com
distinguishedName: CN=Group10,OU=Groups,DC=ranger,DC=qe,DC=hortonworks,DC=com
sAMAccountName: Group10
sn: Group10
@@ -2571,6 +2572,7 @@ member: CN=User1804,CN=Users,DC=ranger,DC=qe,DC=hortonworks,DC=com
member: CN=User1803,CN=Users,DC=ranger,DC=qe,DC=hortonworks,DC=com
member: CN=User1802,CN=Users,DC=ranger,DC=qe,DC=hortonworks,DC=com
member: CN=User1801,CN=Users,DC=ranger,DC=qe,DC=hortonworks,DC=com
+member: CN=Group18,OU=Groups,DC=ranger,DC=qe,DC=hortonworks,DC=com
distinguishedName: CN=Group19,OU=Groups,DC=ranger,DC=qe,DC=hortonworks,DC=com
sAMAccountName: Group19
sn: Group19
http://git-wip-us.apache.org/repos/asf/ranger/blob/f780aba3/ugsync/src/test/resources/ranger-ugsync-site.xml
----------------------------------------------------------------------
diff --git a/ugsync/src/test/resources/ranger-ugsync-site.xml b/ugsync/src/test/resources/ranger-ugsync-site.xml
index 7d1c27c..0a1a86d 100644
--- a/ugsync/src/test/resources/ranger-ugsync-site.xml
+++ b/ugsync/src/test/resources/ranger-ugsync-site.xml
@@ -177,4 +177,9 @@
<name>ranger.usersync.ldap.deltasync</name>
<value>false</value>
</property>
+
+ <property>
+ <name>ranger.usersync.group.hierarchylevels</name>
+ <value>2</value>
+ </property>
</configuration>