blob: e5783cf82afe272cefd24cadd0155c5d71045481 [file] [log] [blame]
/*
* 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.ranger.ldapconfigcheck;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;
import javax.naming.ldap.LdapContext;
import javax.naming.ldap.Control;
import javax.naming.ldap.PagedResultsResponseControl;
import javax.naming.ldap.PagedResultsControl;
import java.io.PrintStream;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;
public class UserSync {
private static String[] userNameAttrValues = { "sAMAccountName", "uid", "cn" };
private static String[] userObjClassValues = { "person", "posixAccount" }; //Not needed as this is read from the second occurence of objectClass attribute from user entry
private static String[] userGroupMemAttrValues = { "memberOf", "ismemberOf"};
private static String[] groupObjectClassValues = { "group", "groupOfNames", "posixGroup" };
private static String[] groupNameAttrValues = { "distinguishedName", "cn" };
private static String[] groupMemAttrValues = { "member", "memberUid" };
private String userNameAttribute = null;
private String userObjClassName = null;
private String userGroupMemberName = null;
private String groupMemberName = null;
private String groupNameAttrName = null;
private String groupObjClassName = null;
private String groupSearchBase = null;
private String groupSearchFilter = null;
private String userSearchBase = null;
private String userSearchFilter = null;
private String searchBase = null;
private String groupName = null;
private PrintStream logFile = null;
private PrintStream ambariProps = null;
private PrintStream installProps = null;
private LdapConfig config = null;
public String getUserNameAttribute() {
return userNameAttribute;
}
public String getUserObjClassName() {
return userObjClassName;
}
public String getUserGroupMemberName() {
return userGroupMemberName;
}
public String getGroupMemberName() {
return groupMemberName;
}
public String getGroupNameAttrName() {
return groupNameAttrName;
}
public String getGroupObjClassName() {
return groupObjClassName;
}
public String getGroupSearchBase() { return groupSearchBase; }
public String getUserSearchBase() { return userSearchBase; }
public String getSearchBase() {
return searchBase;
}
public UserSync(LdapConfig config, PrintStream logFile, PrintStream ambariProps, PrintStream installProps) {
this.config = config;
this.logFile = logFile;
this.ambariProps = ambariProps;
this.installProps = installProps;
initUserSync();
}
private void initUserSync() {
try {
String bindDn = config.getLdapBindDn();
userObjClassName = config.getUserObjectClass();
userNameAttribute = config.getUserNameAttribute();
userGroupMemberName = config.getUserGroupNameAttribute();
userSearchBase = config.getUserSearchBase();
userSearchFilter = config.getUserSearchFilter();
groupObjClassName = config.getGroupObjectClass();
groupNameAttrName = config.getGroupNameAttribute();
groupMemberName = config.getUserGroupMemberAttributeName();
groupSearchBase = config.getGroupSearchBase();
groupSearchFilter = config.getGroupSearchFilter();
//String userName = null;
if (bindDn.contains("@")) {
//userName = bindDn.substring(0, bindDn.indexOf("@"));
searchBase = bindDn.substring(bindDn.indexOf("@") + 1);
searchBase = "dc=".concat(searchBase);
searchBase = searchBase.replaceAll("\\.", ",dc=");
} else {
int dcIndex = bindDn.toLowerCase().indexOf("dc=");
//userName = bindDn.substring(bindDn.indexOf("=") + 1, dcIndex - 1);
searchBase = bindDn.substring(dcIndex);
}
} catch (Throwable t) {
logFile.println("ERROR: Failed to initialize the user sync properties " + t);
}
}
public void findUserProperties(LdapContext ldapContext) throws Throwable {
// 1. find basic user properties
// 2. find user search base and user search filter by passing basic attributes
findBasicUserProperties(ldapContext, true);
findAdvUserProperties(ldapContext, true);
}
/* Use the provided bind dn or the user search base and user search filter for sample user and determine the basic user attribute.
*/
private void findBasicUserProperties(LdapContext ldapContext, boolean isOutputNeeded) throws Throwable{
String bindDn = config.getLdapBindDn();
String userSFilter = config.getUserSearchFilter();
String userSBase = config.getUserSearchBase();
Attribute userNameAttr = null;
Attribute groupMemberAttr;
SearchControls userSearchControls = new SearchControls();
userSearchControls.setSearchScope(config.getUserSearchScope());
userSearchControls.setReturningAttributes(new java.lang.String[]{"*", "+"});
int noOfUsers = 0;
NamingEnumeration<SearchResult> userSearchResultEnum = null;
try {
if (userSBase == null || userSBase.isEmpty()) {
if (bindDn.contains("@")) {
userSBase = bindDn.substring(bindDn.indexOf("@") + 1);
userSBase = "dc=".concat(userSBase);
userSBase = userSBase.replaceAll("\\.", ",dc=");
} else {
//int dcIndex = bindDn.toLowerCase().indexOf("dc=");
userSBase = bindDn.substring(bindDn.indexOf(",") + 1);
}
//System.out.println("Derived user search base = " + userSearchBase);
}
if (userSFilter == null || userSFilter.isEmpty()) {
if (bindDn.contains("@")) {
userSFilter = "userPrincipalName=" + bindDn;
} else {
int cnEndIndex = bindDn.indexOf(",");
userSFilter = bindDn.substring(0,cnEndIndex);
}
//System.out.println("Derived user search filter = " + userSearchFilter);
}
try {
userSearchResultEnum = ldapContext.search(userSBase,
userSFilter, userSearchControls);
while (userSearchResultEnum.hasMore()) {
if (noOfUsers >= 5) {
break;
}
final SearchResult userEntry = userSearchResultEnum.next();
if (userEntry == null) {
logFile.println("WARN: userEntry null");
continue;
}
Attributes attributes = userEntry.getAttributes();
if (attributes == null) {
logFile.println("WARN: Attributes missing for entry " + userEntry.getNameInNamespace());
continue;
}
if (userNameAttribute == null || userNameAttribute.isEmpty()) {
for (int i = 0; i < userNameAttrValues.length; i++) {
userNameAttr = attributes.get(userNameAttrValues[i]);
if (userNameAttr != null) {
userNameAttribute = userNameAttrValues[i];
break;
}
}
if (userNameAttr == null) {
logFile.print("WARN: Failed to find any of ( ");
for (int i = 0; i < userNameAttrValues.length; i++) {
logFile.print(userNameAttrValues[i] + " ");
}
logFile.println(") for entry " + userEntry.getNameInNamespace());
continue;
}
} else {
userNameAttr = attributes.get(userNameAttribute);
if (userNameAttr == null) {
logFile.println("WARN: Failed to find " + userNameAttribute + " for entry " + userEntry.getNameInNamespace());
continue;
}
}
String userName = (String) userNameAttr.get();
if (userName == null || userName.trim().isEmpty()) {
logFile.println("WARN: " + userNameAttribute + " empty for entry " + userEntry.getNameInNamespace());
continue;
}
userName = userName.toLowerCase();
Attribute userObjClassAttr = attributes.get("objectClass");
NamingEnumeration<?> userObjClassEnum = userObjClassAttr.getAll();
String userObjClass = null;
while (userObjClassEnum.hasMore()) {
userObjClass = userObjClassEnum.next().toString();
if (userObjClassName == null || userObjClassName.isEmpty()) {
if (userObjClass != null) {
for (int i = 0; i < userObjClassValues.length; i++) {
if (userObjClass.equalsIgnoreCase(userObjClassValues[i])) {
userObjClassName = userObjClass;
break;
}
}
} else {
logFile.println("WARN: Failed to find objectClass attribute for " + userName);
//continue;
}
}
}
if (userObjClassName == null || userObjClassName.isEmpty()) {
userObjClassName = userObjClass;
}
for (int i = 0; i < userGroupMemAttrValues.length; i++) {
groupMemberAttr = attributes.get(userGroupMemAttrValues[i]);
if (groupMemberAttr != null) {
userGroupMemberName = userGroupMemAttrValues[i];
groupName = groupMemberAttr.get(0).toString();
break;
}
}
noOfUsers++;
}
} catch (NamingException ne) {
String msg = "Exception occured while discovering basic user properties:\n" +
"ranger.usersync.ldap.user.nameattribute\n" +
"ranger.usersync.ldap.user.objectclass\n" +
"ranger.usersync.ldap.user.groupnameattribute\n";
if ((config.getUserSearchBase() != null && !config.getUserSearchBase().isEmpty()) ||
(config.getUserSearchFilter() != null && !config.getUserSearchFilter().isEmpty())) {
throw new Exception(msg + "Please verify values for ranger.usersync.ldap.user.searchbase and ranger.usersync.ldap.user.searchfilter");
} else {
throw new Exception(msg + ne);
}
}
if (isOutputNeeded) {
installProps.println("# Possible values for user search related properties:");
installProps.println("SYNC_LDAP_USER_NAME_ATTRIBUTE=" + userNameAttribute);
installProps.println("SYNC_LDAP_USER_OBJECT_CLASS=" + userObjClassName);
installProps.println("SYNC_LDAP_USER_GROUP_NAME_ATTRIBUTE=" + userGroupMemberName);
ambariProps.println("# Possible values for user search related properties:");
ambariProps.println("ranger.usersync.ldap.user.nameattribute=" + userNameAttribute);
ambariProps.println("ranger.usersync.ldap.user.objectclass=" + userObjClassName);
ambariProps.println("ranger.usersync.ldap.user.groupnameattribute=" + userGroupMemberName);
}
} finally {
try {
if (userSearchResultEnum != null) {
userSearchResultEnum.close();
}
} catch (NamingException ne) {
throw new Exception("Exception occured while closing user search result: " + ne);
}
}
}
private void findAdvUserProperties(LdapContext ldapContext, boolean isOutputNeeded) throws Throwable{
int noOfUsers;
NamingEnumeration<SearchResult> userSearchResultEnum = null;
SearchControls userSearchControls = new SearchControls();
userSearchControls.setSearchScope(config.getUserSearchScope());
if (userNameAttribute != null && !userNameAttribute.isEmpty()) {
Set<String> userSearchAttributes = new HashSet<>();
userSearchAttributes.add(userNameAttribute);
userSearchAttributes.add(userGroupMemberName);
userSearchAttributes.add("distinguishedName");
userSearchControls.setReturningAttributes(userSearchAttributes.toArray(
new String[userSearchAttributes.size()]));
} else {
userSearchControls.setReturningAttributes(new java.lang.String[]{"*", "+"});
}
String extendedUserSearchFilter = "(objectclass=" + userObjClassName + ")";
try {
HashMap<String, Integer> ouOccurences = new HashMap<>();
if (userSearchBase == null || userSearchBase.isEmpty()) {
userSearchResultEnum = ldapContext.search(searchBase,
extendedUserSearchFilter, userSearchControls);
} else {
userSearchResultEnum = ldapContext.search(userSearchBase,
extendedUserSearchFilter, userSearchControls);
}
noOfUsers = 0;
while (userSearchResultEnum.hasMore()) {
if (noOfUsers >= 20) {
break;
}
final SearchResult userEntry = userSearchResultEnum.next();
if (userEntry == null) {
logFile.println("WARN: userEntry null");
continue;
}
Attributes attributes = userEntry.getAttributes();
if (attributes == null) {
logFile.println("WARN: Attributes missing for entry " + userEntry.getNameInNamespace());
continue;
}
String dnValue;
Attribute dnAttr = attributes.get("distinguishedName");
if (dnAttr != null) {
dnValue = dnAttr.get().toString();
String ouStr = "OU=";
int indexOfOU = dnValue.indexOf(ouStr);
if (indexOfOU > 0) {
dnValue = dnValue.substring(indexOfOU);
} else {
dnValue = dnValue.substring(dnValue.indexOf(",") + 1);
}
} else {
// If distinguishedName is not found,
// strip off the userName from the long name for OU or sub domain
dnValue = userEntry.getNameInNamespace();
dnValue = dnValue.substring(dnValue.indexOf(",") + 1);
}
//System.out.println("OU from dn = " + dnValue);
Integer ouOccrs = ouOccurences.get(dnValue);
if (ouOccrs == null) {
//System.out.println("value = 0");
ouOccrs = new Integer(0);
}
int val = ouOccrs.intValue();
ouOccrs = new Integer(++val);
ouOccurences.put(dnValue, ouOccrs);
noOfUsers++;
}
if (!ouOccurences.isEmpty()) {
Set<String> keys = ouOccurences.keySet();
int maxOUOccr = 0;
for (String key : keys) {
int ouOccurVal = ouOccurences.get(key).intValue();
logFile.println("INFO: No. of users from " + key + " = " + ouOccurVal);
if (ouOccurVal > maxOUOccr) {
maxOUOccr = ouOccurVal;
userSearchBase = key;
}
}
}
if (userSearchFilter == null || userSearchFilter.isEmpty()) {
userSearchFilter = userNameAttribute + "=*";
}
if (isOutputNeeded) {
installProps.println("SYNC_LDAP_USER_SEARCH_BASE=" + userSearchBase);
installProps.println("SYNC_LDAP_USER_SEARCH_FILTER=" + userSearchFilter);
ambariProps.println("ranger.usersync.ldap.user.searchbase=" + userSearchBase);
ambariProps.println("ranger.usersync.ldap.user.searchfilter=" + userSearchFilter);
}
} catch (NamingException ne) {
String msg = "Exception occured while discovering user properties:\n" +
"ranger.usersync.ldap.user.searchbase\n" +
"ranger.usersync.ldap.user.searchfilter\n";
if ((config.getUserNameAttribute() != null && !config.getUserNameAttribute().isEmpty()) ||
(config.getUserObjectClass() != null && !config.getUserObjectClass().isEmpty()) ||
(config.getGroupNameAttribute() != null && !config.getGroupNameAttribute().isEmpty())) {
throw new Exception("Please verify values for ranger.usersync.ldap.user.nameattribute, " +
"ranger.usersync.ldap.user.objectclass, and" +
"ranger.usersync.ldap.user.groupnameattribute");
} else {
throw new Exception(msg + ne);
}
} finally {
if (userSearchResultEnum != null) {
userSearchResultEnum.close();
}
}
}
public void getAllUsers(LdapContext ldapContext) throws Throwable {
int noOfUsers = 0;
Attribute userNameAttr = null;
//String groupName = null;
Attribute groupMemberAttr = null;
NamingEnumeration<SearchResult> userSearchResultEnum = null;
SearchControls userSearchControls = new SearchControls();
userSearchControls.setSearchScope(config.getUserSearchScope());
Set<String> userSearchAttributes = new HashSet<>();
if (userNameAttribute != null) {
userSearchAttributes.add(userNameAttribute);
}
if (userGroupMemberName != null) {
userSearchAttributes.add(userGroupMemberName);
}
if (userSearchAttributes.size() > 0) {
userSearchControls.setReturningAttributes(userSearchAttributes.toArray(
new String[userSearchAttributes.size()]));
} else {
userSearchControls.setReturningAttributes(new java.lang.String[]{"*", "+"});
}
String extendedUserSearchFilter = "(objectclass=" + userObjClassName + ")";
if (userSearchFilter != null && !userSearchFilter.trim().isEmpty()) {
String customFilter = userSearchFilter.trim();
if (!customFilter.startsWith("(")) {
customFilter = "(" + customFilter + ")";
}
extendedUserSearchFilter = "(&" + extendedUserSearchFilter + customFilter + ")";
}
byte[] cookie = null;
logFile.println();
logFile.println("INFO: First 20 Users and associated groups are:");
try {
do {
userSearchResultEnum = ldapContext.search(userSearchBase,
extendedUserSearchFilter, userSearchControls);
while (userSearchResultEnum.hasMore()) {
final SearchResult userEntry = userSearchResultEnum.next();
if (userEntry == null) {
logFile.println("WARN: userEntry null");
continue;
}
Attributes attributes = userEntry.getAttributes();
if (attributes == null) {
logFile.println("WARN: Attributes missing for entry " + userEntry.getNameInNamespace());
continue;
}
if (userNameAttribute == null || userNameAttribute.isEmpty()) {
for (int i = 0; i < userNameAttrValues.length; i++) {
userNameAttr = attributes.get(userNameAttrValues[i]);
if (userNameAttr != null) {
userNameAttribute = userNameAttrValues[i];
break;
}
}
if (userNameAttr == null) {
logFile.print("WARN: Failed to find any of ( ");
for (int i = 0; i < userNameAttrValues.length; i++) {
logFile.print(userNameAttrValues[i] + " ");
}
logFile.println(") for entry " + userEntry.getNameInNamespace());
continue;
}
} else {
userNameAttr = attributes.get(userNameAttribute);
if (userNameAttr == null) {
logFile.println("WARN: Failed to find " + userNameAttribute + " for entry " + userEntry.getNameInNamespace());
continue;
}
}
String userName = userNameAttr.get().toString();
if (userName == null || userName.trim().isEmpty()) {
logFile.println("WARN: " + userNameAttribute + " empty for entry " + userEntry.getNameInNamespace());
continue;
}
userName = userName.toLowerCase();
Set<String> groups = new HashSet<>();
groupMemberAttr = attributes.get(userGroupMemberName);
if (groupMemberAttr != null) {
NamingEnumeration<?> groupEnum = groupMemberAttr.getAll();
while (groupEnum.hasMore()) {
String groupRes = groupEnum.next().toString();
groups.add(groupRes);
if (groupName == null || groupName.isEmpty()) {
groupName = groupRes;
}
}
}
if (noOfUsers < 20) {
logFile.println("Username: " + userName + ", Groups: " + groups);
}
noOfUsers++;
}
// 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];
cookie = prrc.getCookie();
}
}
} else {
logFile.println("WARN: No controls were sent from the server");
}
// Re-activate paged results
if (config.isPagedResultsEnabled()) {
ldapContext.setRequestControls(new Control[]{
new PagedResultsControl(config.getPagedResultsSize(), cookie, Control.CRITICAL)});
}
} while (cookie != null);
logFile.println("\nINFO: Total no. of users = " + noOfUsers);
} catch (NamingException ne) {
String msg = "Exception occured while retreiving users\n";
if ((config.getUserNameAttribute() != null && !config.getUserNameAttribute().isEmpty()) ||
(config.getUserObjectClass() != null && !config.getUserObjectClass().isEmpty()) ||
(config.getGroupNameAttribute() != null && !config.getGroupNameAttribute().isEmpty()) ||
(config.getUserSearchBase() != null && !config.getUserSearchBase().isEmpty()) ||
(config.getUserSearchFilter() != null && !config.getUserSearchFilter().isEmpty())) {
throw new Exception("Please verify values for:\n ranger.usersync.ldap.user.nameattribute\n " +
"ranger.usersync.ldap.user.objectclass\n" +
"ranger.usersync.ldap.user.groupnameattribute\n" +
"ranger.usersync.ldap.user.searchbase\n" +
"ranger.usersync.ldap.user.searchfilter\n");
} else {
throw new Exception(msg + ne);
}
} finally {
if (userSearchResultEnum != null) {
userSearchResultEnum.close();
}
}
}
public void findGroupProperties(LdapContext ldapContext) throws Throwable {
// find basic group attributes/properties
// find group search base and group search filter
// Get all groups
if (groupName == null || groupName.isEmpty()) {
// Perform basic user search and get the group name from the user's group attribute name.
findBasicUserProperties(ldapContext, false);
}
if (groupName == null || groupName.isEmpty()) {
// Perform adv user search and get the group name from the user's group attribute name.
findAdvUserProperties(ldapContext, false);
}
findBasicGroupProperties(ldapContext);
findAdvGroupProperties(ldapContext);
}
private void findBasicGroupProperties(LdapContext ldapContext) throws Throwable {
int noOfGroups;
Attribute groupNameAttr;
String groupBase;
String groupFilter;
Attribute groupMemberAttr;
NamingEnumeration<SearchResult> groupSearchResultEnum = null;
SearchControls groupSearchControls = new SearchControls();
groupSearchControls.setSearchScope(config.getGroupSearchScope());
try {
if (groupName == null || groupName.isEmpty()) {
groupSearchResultEnum = ldapContext.search(searchBase, null);
} else {
int baseIndex = groupName.indexOf(",");
groupBase = groupName.substring(baseIndex + 1);
groupFilter = groupName.substring(0, baseIndex);
groupSearchResultEnum = ldapContext.search(groupBase, groupFilter,
groupSearchControls);
}
noOfGroups = 0;
while (groupSearchResultEnum.hasMore()) {
if (noOfGroups >= 1) {
break;
}
final SearchResult groupEntry = groupSearchResultEnum.next();
if (groupEntry == null) {
continue;
}
Attributes groupAttributes = groupEntry.getAttributes();
if (groupAttributes == null) {
logFile.println("WARN: Attributes missing for entry " + groupEntry.getNameInNamespace());
continue;
}
Attribute groupObjClassAttr = groupAttributes.get("objectClass");
if (groupObjClassAttr != null) {
NamingEnumeration<?> groupObjClassEnum = groupObjClassAttr.getAll();
while (groupObjClassEnum.hasMore()) {
String groupObjClassStr = groupObjClassEnum.next().toString();
for (int i = 0; i < groupObjectClassValues.length; i++) {
if (groupObjClassStr.equalsIgnoreCase(groupObjectClassValues[i])) {
groupObjClassName = groupObjClassStr;
break;
}
}
}
} else {
logFile.println("WARN: Failed to find group objectClass attribute for " + groupEntry.getNameInNamespace());
continue;
}
if (groupNameAttrName == null || groupNameAttrName.isEmpty()) {
for (int i = 0; i < groupNameAttrValues.length; i++) {
groupNameAttr = groupAttributes.get(groupNameAttrValues[i]);
if (groupNameAttr != null) {
groupNameAttrName = groupNameAttrValues[i];
break;
}
}
}
for (int i = 0; i < groupMemAttrValues.length; i++) {
groupMemberAttr = groupAttributes.get(groupMemAttrValues[i]);
if (groupMemberAttr != null) {
groupMemberName = groupMemAttrValues[i];
break;
}
}
noOfGroups++;
}
installProps.println("\n# Possible values for group search related properties:");
installProps.println("SYNC_GROUP_MEMBER_ATTRIBUTE_NAME=" + groupMemberName);
installProps.println("SYNC_GROUP_NAME_ATTRIBUTE=" + groupNameAttrName);
installProps.println("SYNC_GROUP_OBJECT_CLASS=" + groupObjClassName);
ambariProps.println("\n# Possible values for group search related properties:");
ambariProps.println("ranger.usersync.group.memberattributename=" + groupMemberName);
ambariProps.println("ranger.usersync.group.nameattribute=" + groupNameAttrName);
ambariProps.println("ranger.usersync.group.objectclass=" + groupObjClassName);
} finally {
if (groupSearchResultEnum != null) {
groupSearchResultEnum.close();
}
}
}
private void findAdvGroupProperties(LdapContext ldapContext) throws Throwable {
int noOfGroups = 0;
NamingEnumeration<SearchResult> groupSearchResultEnum = null;
SearchControls groupSearchControls = new SearchControls();
groupSearchControls.setSearchScope(config.getGroupSearchScope());
Set<String> groupSearchAttributes = new HashSet<>();
groupSearchAttributes.add(groupNameAttrName);
groupSearchAttributes.add(groupMemberName);
groupSearchAttributes.add("distinguishedName");
groupSearchControls.setReturningAttributes(groupSearchAttributes.toArray(
new String[groupSearchAttributes.size()]));
String extendedGroupSearchFilter = "(objectclass=" + groupObjClassName + ")";
try {
HashMap<String, Integer> ouOccurences = new HashMap<>();
if (groupSearchBase == null || groupSearchBase.isEmpty()) {
groupSearchResultEnum = ldapContext.search(searchBase, extendedGroupSearchFilter,
groupSearchControls);
} else {
groupSearchResultEnum = ldapContext.search(groupSearchBase, extendedGroupSearchFilter,
groupSearchControls);
}
while (groupSearchResultEnum.hasMore()) {
if (noOfGroups >= 20) {
break;
}
final SearchResult groupEntry = groupSearchResultEnum.next();
if (groupEntry == null) {
continue;
}
Attributes groupAttributes = groupEntry.getAttributes();
if (groupAttributes == null) {
logFile.println("WARN: Attributes missing for entry " + groupEntry.getNameInNamespace());
continue;
}
String dnValue;
Attribute dnAttr = groupAttributes.get("distinguishedName");
if (dnAttr != null) {
dnValue = dnAttr.get().toString();
String ouStr = "OU=";
int indexOfOU = dnValue.indexOf(ouStr);
if (indexOfOU > 0) {
dnValue = dnValue.substring(indexOfOU);
} else {
dnValue = dnValue.substring(dnValue.indexOf(",") + 1);
}
} else {
// If distinguishedName is not found,
// strip off the userName from the long name for OU or sub domain
dnValue = groupEntry.getNameInNamespace();
dnValue = dnValue.substring(dnValue.indexOf(",") + 1);
}
//System.out.println("OU from dn = " + dnValue);
Integer ouOccrs = ouOccurences.get(dnValue);
if (ouOccrs == null) {
//System.out.println("value = 0");
ouOccrs = new Integer(0);
}
int val = ouOccrs.intValue();
ouOccrs = new Integer(++val);
ouOccurences.put(dnValue, ouOccrs);
noOfGroups++;
}
if (!ouOccurences.isEmpty()) {
Set<String> keys = ouOccurences.keySet();
int maxOUOccr = 0;
for (String key : keys) {
int ouOccurVal = ouOccurences.get(key).intValue();
logFile.println("INFO: No. of groups from " + key + " = " + ouOccurVal);
if (ouOccurVal > maxOUOccr) {
maxOUOccr = ouOccurVal;
groupSearchBase = key;
}
}
}
if (groupSearchFilter == null || groupSearchFilter.isEmpty()) {
groupSearchFilter = groupNameAttrName + "=*";
}
installProps.println("SYNC_GROUP_SEARCH_BASE=" + groupSearchBase);
installProps.println("SYNC_LDAP_GROUP_SEARCH_FILTER=" + groupSearchFilter);
ambariProps.println("ranger.usersync.group.searchbase=" + groupSearchBase);
ambariProps.println("ranger.usersync.group.searchfilter=" + groupSearchFilter);
} finally {
if (groupSearchResultEnum != null) {
groupSearchResultEnum.close();
}
}
}
public void getAllGroups(LdapContext ldapContext) throws Throwable {
int noOfGroups = 0;
Attribute groupNameAttr;
Attribute groupMemberAttr;
NamingEnumeration<SearchResult> groupSearchResultEnum = null;
SearchControls groupSearchControls = new SearchControls();
groupSearchControls.setSearchScope(config.getGroupSearchScope());
Set<String> groupSearchAttributes = new HashSet<>();
groupSearchAttributes.add(groupNameAttrName);
groupSearchAttributes.add(groupMemberName);
groupSearchAttributes.add("distinguishedName");
groupSearchControls.setReturningAttributes(groupSearchAttributes.toArray(
new String[groupSearchAttributes.size()]));
String extendedGroupSearchFilter= "(objectclass=" + groupObjClassName + ")";
if (groupSearchFilter != null && !groupSearchFilter.trim().isEmpty()) {
String customFilter = groupSearchFilter.trim();
if (!customFilter.startsWith("(")) {
customFilter = "(" + customFilter + ")";
}
extendedGroupSearchFilter = "(&" + extendedGroupSearchFilter + customFilter + ")";
}
try {
groupSearchResultEnum = ldapContext.search(groupSearchBase, extendedGroupSearchFilter,
groupSearchControls);
logFile.println("\nINFO: First 20 Groups and associated Users are:");
while (groupSearchResultEnum.hasMore()) {
final SearchResult groupEntry = groupSearchResultEnum.next();
if (groupEntry == null) {
continue;
}
Attributes groupAttributes = groupEntry.getAttributes();
if (groupAttributes == null) {
logFile.println("WARN: Attributes missing for entry " + groupEntry.getNameInNamespace());
continue;
}
groupMemberAttr = groupAttributes.get(groupMemberName);
Set<String> users = new HashSet<>();
if (groupMemberAttr != null) {
NamingEnumeration<?> userEnum = groupMemberAttr.getAll();
while (userEnum.hasMore()) {
String userRes = userEnum.next().toString();
users.add(userRes);
}
}
groupNameAttr = groupAttributes.get(groupNameAttrName);
if (noOfGroups < 20) {
logFile.println("Group name: " + groupNameAttr.get().toString() + ", Users: " + users);
}
noOfGroups++;
}
logFile.println("\nINFO: Total no. of groups = " + noOfGroups);
} catch (NamingException ne) {
String msg = "Exception occured while retreiving groups\n";
if ((config.getGroupNameAttribute() != null && !config.getGroupNameAttribute().isEmpty()) ||
(config.getGroupObjectClass() != null && !config.getGroupObjectClass().isEmpty()) ||
(config.getUserGroupMemberAttributeName() != null && !config.getUserGroupMemberAttributeName().isEmpty()) ||
(config.getGroupSearchBase() != null && !config.getGroupSearchBase().isEmpty()) ||
(config.getGroupSearchFilter() != null && !config.getGroupSearchFilter().isEmpty())) {
throw new Exception("Please verify values for:\n ranger.usersync.group.memberattributename\n " +
"ranger.usersync.group.nameattribute\n" +
"ranger.usersync.group.objectclass\n" +
"ranger.usersync.group.searchbase\n" +
"ranger.usersync.group.searchfilter\n");
} else {
throw new Exception(msg + ne);
}
} finally {
if (groupSearchResultEnum != null) {
groupSearchResultEnum.close();
}
}
}
}