You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ranger.apache.org by ma...@apache.org on 2015/10/27 02:08:40 UTC
[22/33] incubator-ranger git commit: RANGER-652: Adding support for
ldap connection check tool
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/5ce7cc38/ugsync/ldapconfigchecktool/ldapconfigcheck/src/main/java/org/apache/ranger/ldapconfigcheck/UserSync.java
----------------------------------------------------------------------
diff --git a/ugsync/ldapconfigchecktool/ldapconfigcheck/src/main/java/org/apache/ranger/ldapconfigcheck/UserSync.java b/ugsync/ldapconfigchecktool/ldapconfigcheck/src/main/java/org/apache/ranger/ldapconfigcheck/UserSync.java
new file mode 100644
index 0000000..53da9f2
--- /dev/null
+++ b/ugsync/ldapconfigchecktool/ldapconfigcheck/src/main/java/org/apache/ranger/ldapconfigcheck/UserSync.java
@@ -0,0 +1,860 @@
+/*
+ * 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 >= 1) {
+ 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(1).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<>();
+
+ userSearchResultEnum = ldapContext.search(searchBase,
+ 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;
+ }
+ }
+ }
+ 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;
+ 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 {
+ 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<>();
+
+ groupSearchResultEnum = ldapContext.search(searchBase, 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;
+ }
+ }
+ }
+
+ 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();
+ }
+ }
+ }
+}
+
+