Return-Path: X-Original-To: apmail-ranger-commits-archive@www.apache.org Delivered-To: apmail-ranger-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 21A6D1761A for ; Sat, 10 Oct 2015 16:30:37 +0000 (UTC) Received: (qmail 64800 invoked by uid 500); 10 Oct 2015 16:30:37 -0000 Delivered-To: apmail-ranger-commits-archive@ranger.apache.org Received: (qmail 64769 invoked by uid 500); 10 Oct 2015 16:30:37 -0000 Mailing-List: contact commits-help@ranger.incubator.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@ranger.incubator.apache.org Delivered-To: mailing list commits@ranger.incubator.apache.org Received: (qmail 64760 invoked by uid 99); 10 Oct 2015 16:30:36 -0000 Received: from Unknown (HELO spamd1-us-west.apache.org) (209.188.14.142) by apache.org (qpsmtpd/0.29) with ESMTP; Sat, 10 Oct 2015 16:30:36 +0000 Received: from localhost (localhost [127.0.0.1]) by spamd1-us-west.apache.org (ASF Mail Server at spamd1-us-west.apache.org) with ESMTP id 6E7BBC53C2 for ; Sat, 10 Oct 2015 16:30:36 +0000 (UTC) X-Virus-Scanned: Debian amavisd-new at spamd1-us-west.apache.org X-Spam-Flag: NO X-Spam-Score: 0.791 X-Spam-Level: X-Spam-Status: No, score=0.791 tagged_above=-999 required=6.31 tests=[KAM_ASCII_DIVIDERS=0.8, T_RP_MATCHES_RCVD=-0.01, URIBL_BLOCKED=0.001] autolearn=disabled Received: from mx1-eu-west.apache.org ([10.40.0.8]) by localhost (spamd1-us-west.apache.org [10.40.0.7]) (amavisd-new, port 10024) with ESMTP id lsU2pi4sSg_W for ; Sat, 10 Oct 2015 16:30:27 +0000 (UTC) Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by mx1-eu-west.apache.org (ASF Mail Server at mx1-eu-west.apache.org) with SMTP id 3A37420382 for ; Sat, 10 Oct 2015 16:30:25 +0000 (UTC) Received: (qmail 64668 invoked by uid 99); 10 Oct 2015 16:30:24 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Sat, 10 Oct 2015 16:30:24 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id 3F06DE049D; Sat, 10 Oct 2015 16:30:24 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: vel@apache.org To: commits@ranger.incubator.apache.org Date: Sat, 10 Oct 2015 16:30:25 -0000 Message-Id: In-Reply-To: <950366e798a24d6fa8620d5fe50488b5@git.apache.org> References: <950366e798a24d6fa8620d5fe50488b5@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: [2/2] incubator-ranger git commit: RANGER-652: Adding support for ldap connection check tool RANGER-652: Adding support for ldap connection check tool Signed-off-by: Velmurugan Periasamy Project: http://git-wip-us.apache.org/repos/asf/incubator-ranger/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-ranger/commit/4c29c547 Tree: http://git-wip-us.apache.org/repos/asf/incubator-ranger/tree/4c29c547 Diff: http://git-wip-us.apache.org/repos/asf/incubator-ranger/diff/4c29c547 Branch: refs/heads/ranger-0.5 Commit: 4c29c547a5285e6e68633368716c3903ac7e0892 Parents: 7296109 Author: Sailaja Polavarapu Authored: Fri Oct 9 10:07:01 2015 -0700 Committer: Velmurugan Periasamy Committed: Sat Oct 10 12:30:10 2015 -0400 ---------------------------------------------------------------------- src/main/assembly/usersync.xml | 36 + .../ldapconfigcheck/conf/input.properties | 63 ++ .../ldapconfigchecktool/ldapconfigcheck/pom.xml | 130 +++ .../ldapconfigcheck/scripts/run.sh | 72 ++ .../ldapconfigcheck/AuthenticationCheck.java | 208 +++++ .../ldapconfigcheck/CommandLineOptions.java | 230 +++++ .../ranger/ldapconfigcheck/LdapConfig.java | 436 ++++++++++ .../ldapconfigcheck/LdapConfigCheckMain.java | 241 ++++++ .../apache/ranger/ldapconfigcheck/UserSync.java | 860 +++++++++++++++++++ 9 files changed, 2276 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/4c29c547/src/main/assembly/usersync.xml ---------------------------------------------------------------------- diff --git a/src/main/assembly/usersync.xml b/src/main/assembly/usersync.xml index 8c2600e..161a443 100644 --- a/src/main/assembly/usersync.xml +++ b/src/main/assembly/usersync.xml @@ -134,6 +134,42 @@ 544 + + 755 + 755 + /ldaptool + ugsync/ldapconfigchecktool/ldapconfigcheck/scripts + + run.sh + + + + 755 + 644 + /ldaptool/lib + ugsync/ldapconfigchecktool/ldapconfigcheck/target + + ldapconfigcheck.jar + + + + 755 + 644 + /ldaptool/conf + ugsync/ldapconfigchecktool/ldapconfigcheck/conf + + input.properties + + + + 755 + 644 + /ldaptool/output + ugsync/ldapconfigchecktool/ldapconfigcheck/conf + + input.properties + + http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/4c29c547/ugsync/ldapconfigchecktool/ldapconfigcheck/conf/input.properties ---------------------------------------------------------------------- diff --git a/ugsync/ldapconfigchecktool/ldapconfigcheck/conf/input.properties b/ugsync/ldapconfigchecktool/ldapconfigcheck/conf/input.properties new file mode 100755 index 0000000..dc6fc59 --- /dev/null +++ b/ugsync/ldapconfigchecktool/ldapconfigcheck/conf/input.properties @@ -0,0 +1,63 @@ +# 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. +# +# Mandatory ldap configuration properties. +ranger.usersync.ldap.url= +ranger.usersync.ldap.binddn= +ranger.usersync.ldap.ldapbindpassword= + +# Mandatory only for openLdap +ranger.usersync.ldap.user.searchbase= +ranger.usersync.ldap.user.searchfilter= + +# For verifying authentication please provide sample username and password +ranger.admin.auth.sampleuser= +ranger.admin.auth.samplepassword= + +# Optional properties will be determined based on the above search +# User attributes +ranger.usersync.ldap.user.nameattribute= +ranger.usersync.ldap.user.objectclass= +ranger.usersync.ldap.user.groupnameattribute= + +# Group attributes +ranger.usersync.group.searchenabled=false +ranger.usersync.group.memberattributename= +ranger.usersync.group.nameattribute= +ranger.usersync.group.objectclass= +ranger.usersync.group.searchbase= +ranger.usersync.group.searchfilter= + +# Other UserSync related attributes +ranger.usersync.ldap.authentication.mechanism=simple +ranger.usersync.pagedresultsenabled=true +ranger.usersync.pagedresultssize=500 +ranger.usersync.ldap.username.caseconversion=lower +ranger.usersync.ldap.groupname.caseconversion=lower +ranger.usersync.ldap.user.searchscope=sub +ranger.usersync.group.searchscope=sub + +ranger.usersync.credstore.filename= +ranger.usersync.ldap.bindalias= +ranger.usersync.ldap.searchBase= +ranger.usersync.group.usermapsyncenabled=false + +# Authentication properties +ranger.authentication.method= +ranger.ldap.ad.domain= +ranger.ldap.user.dnpattern= +ranger.ldap.group.roleattribute= +ranger.ldap.group.searchbase= +ranger.ldap.group.searchfilter= http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/4c29c547/ugsync/ldapconfigchecktool/ldapconfigcheck/pom.xml ---------------------------------------------------------------------- diff --git a/ugsync/ldapconfigchecktool/ldapconfigcheck/pom.xml b/ugsync/ldapconfigchecktool/ldapconfigcheck/pom.xml new file mode 100644 index 0000000..a0971f2 --- /dev/null +++ b/ugsync/ldapconfigchecktool/ldapconfigcheck/pom.xml @@ -0,0 +1,130 @@ + + + + 4.0.0 + + + org.apache.ranger + ranger + 0.5.0 + .. + + + ldapconfigcheck + + jar + Ldap Config Check Tool + Ldap configuration check tool + + + + commons-cli + commons-cli + ${commons.cli.version} + + + commons-configuration + commons-configuration + ${commons.configuration.version} + + + commons-lang + commons-lang + ${commons.lang.version} + + + commons-logging + commons-logging + ${commons.logging.version} + + + org.springframework + spring-beans + ${springframework.version} + + + org.springframework + spring-context + ${springframework.version} + + + org.springframework + spring-core + ${springframework.version} + + + org.springframework + spring-tx + ${springframework.version} + + + org.springframework.ldap + spring-ldap-core + ${spring-ldap-core.version} + + + org.springframework.security + spring-security-core + ${springframework.security.version} + + + org.springframework.security + spring-security-ldap + ${springframework.security.version} + + + org.apache.ranger + credentialbuilder + ${project.version} + + + + org.apache.ranger + ranger-util + ${project.version} + + + + + ldapconfigcheck + + + org.apache.maven.plugins + maven-shade-plugin + 2.2 + + + package + + shade + + + + + org.apache.ranger.ldapconfigcheck.LdapConfigCheckMain + + + + + + + + + http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/4c29c547/ugsync/ldapconfigchecktool/ldapconfigcheck/scripts/run.sh ---------------------------------------------------------------------- diff --git a/ugsync/ldapconfigchecktool/ldapconfigcheck/scripts/run.sh b/ugsync/ldapconfigchecktool/ldapconfigcheck/scripts/run.sh new file mode 100755 index 0000000..787e216 --- /dev/null +++ b/ugsync/ldapconfigchecktool/ldapconfigcheck/scripts/run.sh @@ -0,0 +1,72 @@ +#!/bin/bash +# 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. + + +AUTH=1 + +usage() { + echo "usage: run.sh + -noauth ignore authentication properties + -d {all|users|groups} + -h show help. + -i Input file name + -o Output directory + -r {all|users|groups}" + exit 1 +} + +cdir=`pwd` +cp="${cdir}/lib/*:${cdir}/conf" +OUTDIR="${cdir}/output/" +JAVA_CMD="java -cp ${cdir}/lib/ldapconfigcheck.jar:${cp} org.apache.ranger.ldapconfigcheck.LdapConfigCheckMain" + +while getopts "i:o:d:r:noauthh" opt; do + case $opt in + i) INFILE=$OPTARG + JAVA_CMD="$JAVA_CMD -i $OPTARG" + ;; + o) OUTDIR=$OPTARG + ;; + d) DISCOVER=$OPTARG + JAVA_CMD="$JAVA_CMD -d $OPTARG" + ;; + r) RETRIEVE=$OPTARG + JAVA_CMD="$JAVA_CMD -r $OPTARG" + ;; + noauth) AUTH=0 + JAVA_CMD="$JAVA_CMD -noauth" + ;; + h) usage + ;; + \?) echo -e \\n"Option -$OPTARG not allowed." + usage + ;; + esac +done + +JAVA_CMD="$JAVA_CMD -o $OUTDIR" + +echo "JAVA commnad = $JAVA_CMD" + +if [ "${JAVA_HOME}" != "" ] +then + export JAVA_HOME + PATH="${JAVA_HOME}/bin:${PATH}" + export PATH +fi + +cd ${cdir} +$JAVA_CMD http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/4c29c547/ugsync/ldapconfigchecktool/ldapconfigcheck/src/main/java/org/apache/ranger/ldapconfigcheck/AuthenticationCheck.java ---------------------------------------------------------------------- diff --git a/ugsync/ldapconfigchecktool/ldapconfigcheck/src/main/java/org/apache/ranger/ldapconfigcheck/AuthenticationCheck.java b/ugsync/ldapconfigchecktool/ldapconfigcheck/src/main/java/org/apache/ranger/ldapconfigcheck/AuthenticationCheck.java new file mode 100644 index 0000000..f39f782 --- /dev/null +++ b/ugsync/ldapconfigchecktool/ldapconfigcheck/src/main/java/org/apache/ranger/ldapconfigcheck/AuthenticationCheck.java @@ -0,0 +1,208 @@ +/* + * 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 java.io.PrintStream; +import java.util.ArrayList; +import java.util.List; +import org.springframework.ldap.core.support.LdapContextSource; +import org.springframework.security.authentication.BadCredentialsException; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.User; +import org.springframework.security.ldap.userdetails.DefaultLdapAuthoritiesPopulator; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.ldap.search.FilterBasedLdapUserSearch; +import org.springframework.security.ldap.authentication.BindAuthenticator; +import org.springframework.security.ldap.authentication.LdapAuthenticationProvider; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.ldap.DefaultSpringSecurityContextSource; + + +public class AuthenticationCheck { + private String ldapUrl = null; + private String authMethod = "NONE"; + private String adDomain = null; + private String userDnPattern = null; + private String roleAttribute = null; + private String groupSearchBase = null; + private String groupSearchFilter = null; + + private PrintStream logFile = null; + private PrintStream ambariProps = null; + private PrintStream installProps = null; + + public AuthenticationCheck(String ldapUrl, UserSync userSyncObj, PrintStream logFile, + PrintStream ambariProps, PrintStream installProps) { + + this.logFile = logFile; + this.ambariProps = ambariProps; + this.installProps = installProps; + + if (userSyncObj.getUserNameAttribute().equalsIgnoreCase("sAMAccountName")) { + authMethod = "AD"; + } else { + authMethod = "LDAP"; + } + this.ldapUrl = ldapUrl; + adDomain = userSyncObj.getSearchBase(); + userDnPattern = userSyncObj.getUserNameAttribute() + "={0}," + userSyncObj.getUserSearchBase(); + roleAttribute = userSyncObj.getGroupNameAttrName(); + groupSearchBase = userSyncObj.getGroupSearchBase(); + groupSearchFilter = userSyncObj.getGroupMemberName() + "=" + userDnPattern; + + } + + public void discoverAuthProperties() { + + ambariProps.println("\n# Possible values for authetication properties:"); + installProps.println("\n# Possible values for authetication properties:"); + if (authMethod.equalsIgnoreCase("AD")) { + installProps.println("xa_ldap_ad_url=" + ldapUrl); + installProps.println("xa_ldap_ad_domain=" + adDomain); + } else { + installProps.println("xa_ldap_url=" + ldapUrl); + installProps.println("xa_ldap_userDNpattern=" + userDnPattern); + installProps.println("xa_ldap_groupRoleAttribute=" + roleAttribute); + installProps.println("xa_ldap_groupSearchBase=" + groupSearchBase); + installProps.println("xa_ldap_groupSearchFilter=" + groupSearchFilter); + } + + ambariProps.println("ranger.authentication.method=" + authMethod); + if (authMethod.equalsIgnoreCase("AD")) { + ambariProps.println("ranger.ldap.ad.url=" + ldapUrl); + ambariProps.println("ranger.ldap.ad.domain=" + adDomain); + } else { + ambariProps.println("ranger.ldap.url=" + ldapUrl); + ambariProps.println("ranger.ldap.user.dnpattern=" + userDnPattern); + ambariProps.println("ranger.ldap.group.roleattribute=" + roleAttribute); + ambariProps.println("ranger.ldap.group.searchbase=" + groupSearchBase); + ambariProps.println("ranger.ldap.group.searchfilter=" + groupSearchFilter); + } + } + + public boolean isAuthenticated(String ldapUrl, String bindDn, String bindPassword, String userName, + String userPassword) { + boolean isAuthenticated = false; + //Verify Authentication + Authentication authentication; + if (authMethod.equalsIgnoreCase("AD")) { + authentication = getADBindAuthentication(ldapUrl, bindDn, bindPassword, userName, userPassword); + } else { + authentication = getLdapBindAuthentication(ldapUrl, bindDn, bindPassword, userName, userPassword); + } + if (authentication != null) { + isAuthenticated = authentication.isAuthenticated(); + } + + return isAuthenticated; + } + + private Authentication getADBindAuthentication(String ldapUrl, String bindDn, String bindPassword, + String userName, String userPassword) { + Authentication result = null; + try { + LdapContextSource ldapContextSource = new DefaultSpringSecurityContextSource(ldapUrl); + ldapContextSource.setUserDn(bindDn); + ldapContextSource.setPassword(bindPassword); + ldapContextSource.setReferral("follow"); + ldapContextSource.setCacheEnvironmentProperties(true); + ldapContextSource.setAnonymousReadOnly(false); + ldapContextSource.setPooled(true); + ldapContextSource.afterPropertiesSet(); + + String searchFilter="(sAMAccountName={0})"; + FilterBasedLdapUserSearch userSearch=new FilterBasedLdapUserSearch(adDomain, searchFilter,ldapContextSource); + userSearch.setSearchSubtree(true); + + BindAuthenticator bindAuthenticator = new BindAuthenticator(ldapContextSource); + bindAuthenticator.setUserSearch(userSearch); + bindAuthenticator.afterPropertiesSet(); + + LdapAuthenticationProvider ldapAuthenticationProvider = new LdapAuthenticationProvider(bindAuthenticator); + + if (userName != null && userPassword != null && !userName.trim().isEmpty() && !userPassword.trim().isEmpty()) { + final List grantedAuths = new ArrayList<>(); + grantedAuths.add(new SimpleGrantedAuthority("ROLE_USER")); + final UserDetails principal = new User(userName, userPassword, grantedAuths); + final Authentication finalAuthentication = new UsernamePasswordAuthenticationToken(principal, userPassword, grantedAuths); + + result = ldapAuthenticationProvider.authenticate(finalAuthentication); + } + + } catch (BadCredentialsException bce) { + logFile.println("ERROR: LDAP Authentication Failed. Please verify values for ranger.admin.auth.sampleuser and " + + "ranger.admin.auth.samplepassword\n"); + } catch (Exception e) { + logFile.println("ERROR: LDAP Authentication Failed: " + e); + } + return result; + } + + private Authentication getLdapBindAuthentication(String ldapUrl, String bindDn, String bindPassword, + String userName, String userPassword) { + Authentication result = null; + try { + LdapContextSource ldapContextSource = new DefaultSpringSecurityContextSource(ldapUrl); + ldapContextSource.setUserDn(bindDn); + ldapContextSource.setPassword(bindPassword); + ldapContextSource.setReferral("follow"); + ldapContextSource.setCacheEnvironmentProperties(false); + ldapContextSource.setAnonymousReadOnly(true); + ldapContextSource.setPooled(true); + ldapContextSource.afterPropertiesSet(); + + DefaultLdapAuthoritiesPopulator defaultLdapAuthoritiesPopulator = new DefaultLdapAuthoritiesPopulator(ldapContextSource, groupSearchBase); + defaultLdapAuthoritiesPopulator.setGroupRoleAttribute(roleAttribute); + defaultLdapAuthoritiesPopulator.setGroupSearchFilter(groupSearchFilter); + defaultLdapAuthoritiesPopulator.setIgnorePartialResultException(true); + + String searchFilter="(uid={0})"; + FilterBasedLdapUserSearch userSearch=new FilterBasedLdapUserSearch(adDomain, searchFilter,ldapContextSource); + userSearch.setSearchSubtree(true); + + BindAuthenticator bindAuthenticator = new BindAuthenticator(ldapContextSource); + bindAuthenticator.setUserSearch(userSearch); + String[] userDnPatterns = new String[] { userDnPattern }; + bindAuthenticator.setUserDnPatterns(userDnPatterns); + bindAuthenticator.afterPropertiesSet(); + + LdapAuthenticationProvider ldapAuthenticationProvider = new LdapAuthenticationProvider(bindAuthenticator,defaultLdapAuthoritiesPopulator); + + if (userName != null && userPassword != null && !userName.trim().isEmpty()&& !userPassword.trim().isEmpty()) { + final List grantedAuths = new ArrayList<>(); + grantedAuths.add(new SimpleGrantedAuthority("ROLE_USER")); + final UserDetails principal = new User(userName, userPassword,grantedAuths); + final Authentication finalAuthentication = new UsernamePasswordAuthenticationToken(principal, userPassword, grantedAuths); + + result = ldapAuthenticationProvider.authenticate(finalAuthentication); + } + } catch (BadCredentialsException bce) { + logFile.println("ERROR: LDAP Authentication Failed. Please verify values for ranger.admin.auth.sampleuser and " + + "ranger.admin.auth.samplepassword\n"); + } catch (Exception e) { + logFile.println("ERROR: LDAP Authentication Failed: " + e); + } + return result; + } +} + + http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/4c29c547/ugsync/ldapconfigchecktool/ldapconfigcheck/src/main/java/org/apache/ranger/ldapconfigcheck/CommandLineOptions.java ---------------------------------------------------------------------- diff --git a/ugsync/ldapconfigchecktool/ldapconfigcheck/src/main/java/org/apache/ranger/ldapconfigcheck/CommandLineOptions.java b/ugsync/ldapconfigchecktool/ldapconfigcheck/src/main/java/org/apache/ranger/ldapconfigcheck/CommandLineOptions.java new file mode 100644 index 0000000..790330f --- /dev/null +++ b/ugsync/ldapconfigchecktool/ldapconfigcheck/src/main/java/org/apache/ranger/ldapconfigcheck/CommandLineOptions.java @@ -0,0 +1,230 @@ +/* + * 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 org.apache.commons.cli.*; +import java.io.Console; + +public class CommandLineOptions { + + private String[] args = null; + private Options options = new Options(); + private String input = null; + private String output = null; + private String discoverProperties; + private String retrieveValues = null; + private boolean isAuthEnabled = true; + private String ldapUrl = ""; + private String bindDn = ""; + private String bindPassword = ""; + private String userSearchBase = ""; + private String userSearchFilter = ""; + private String authUser = ""; + private String authPass = ""; + + public CommandLineOptions(String[] args) { + this.args = args; + options.addOption("h", "help", false, "show help."); + options.addOption("i", "inputfile", true, "Input file name"); + options.addOption("o", "outputdir", true, "Output directory"); + options.addOption("d", "discoverProperties", true, "{all|users|groups}"); + options.addOption("r", "retrieve", true, "{all|users|groups}"); + options.addOption("noauth", "noAuthentication", false, "Ignore authentication properties"); + } + + public void parse() { + CommandLineParser parser = new BasicParser(); + try { + CommandLine cmd = parser.parse(options, args); + if (cmd.hasOption("h")) { + + } + + + if (cmd.hasOption("o")) { + output = cmd.getOptionValue("o"); + } else { + System.out.println("Missing o option for output directory"); + help(); + } + + if (cmd.hasOption("d")) { + discoverProperties = cmd.getOptionValue("d"); + if (discoverProperties == null || (!discoverProperties.equalsIgnoreCase("all") && + !discoverProperties.equalsIgnoreCase("users") && !discoverProperties.equalsIgnoreCase("groups"))) { + System.out.println("Unsupported value for option d"); + help(); + } + } + + if (cmd.hasOption("r")) { + retrieveValues = cmd.getOptionValue("r"); + if (retrieveValues == null || (!retrieveValues.equalsIgnoreCase("all") + && !retrieveValues.equalsIgnoreCase("users") && !retrieveValues.equalsIgnoreCase("groups"))) { + System.out.println("Unsupported value for option r"); + help(); + } + } else { + if (discoverProperties == null || discoverProperties.isEmpty()) { + System.out.println("Default to discover all usersync properties"); + //help(); + // If "d" or "r" option is not specified, then default to discover all usersync properties + discoverProperties = "all"; + } + } + + if (cmd.hasOption("noauth")) { + isAuthEnabled = false; + } + + if (cmd.hasOption("i")) { + input = cmd.getOptionValue("i"); + if (input == null || input.isEmpty()) { + System.out.println("Please specify the input properties file name"); + help(); + } + + } else { + // Read the properties from CLI and write to the input properties file. + input = LdapConfig.CONFIG_FILE; + readCLI(); + } + + } catch (ParseException pe) { + System.out.println("Failed to parse command line arguments " + pe); + help(); + } + } + + public void help() { + // This prints out some help + HelpFormatter formater = new HelpFormatter(); + formater.printHelp("ldapConfigCheck", options); + System.exit(0); + } + + public String getInput() { + return input; + } + + public String getOutput() { + + return output; + } + + public String getDiscoverProperties() { + return discoverProperties; + } + + public boolean isAuthEnabled() { + return isAuthEnabled; + } + + public String getRetrieveValues() { + return retrieveValues; + } + + private void readCLI() { + boolean repeat; + Console console = System.console(); + do { + repeat = false; + System.out.print("Ldap url [ldap://ldap.example.com:389]: "); + ldapUrl = console.readLine(); + if (ldapUrl == null || ldapUrl.isEmpty()) { + System.out.println("Please enter valid ldap url."); + repeat = true; + } + } while (repeat == true); + do { + repeat = false; + System.out.print("Bind DN [cn=admin,ou=users,dc=example,dc=com]: "); + bindDn = console.readLine(); + if (bindDn == null || bindDn.isEmpty()) { + System.out.println("Please enter valid bindDn."); + repeat = true; + } + } while (repeat == true); + do { + repeat = false; + System.out.print("Bind Password: "); + char[] password = console.readPassword(); + bindPassword = String.valueOf(password); + if (bindPassword == null || bindPassword.isEmpty()) { + System.out.println("Bind Password can't be empty."); + repeat = true; + } + } while (repeat == true); + System.out.print("User Search Base [ou=users,dc=example,dc=com]: "); + userSearchBase = console.readLine(); + System.out.print("User Search Filter [cn=user1]: "); + userSearchFilter = console.readLine(); + + if (isAuthEnabled) { + do { + repeat = false; + System.out.print("Sample Authentication User [user1]: "); + authUser = console.readLine(); + if (authUser == null || authUser.isEmpty()) { + System.out.println("Sample Authentication user must not be empty!"); + repeat = true; + } + } while (repeat == true); + do { + repeat = false; + System.out.print("Sample Authentication Password: "); + char[] password = console.readPassword(); + authPass = String.valueOf(password); + if (authPass == null || authPass.isEmpty()) { + System.out.println("Sample Authentication password must not be empty!"); + repeat = true; + } + } while (repeat == true); + } + } + + public String getLdapUrl() { + return ldapUrl; + } + + public String getBindDn() { + return bindDn; + } + + public String getBindPassword() { + return bindPassword; + } + + public String getUserSearchBase() { + return userSearchBase; + } + + public String getUserSearchFilter() { + return userSearchFilter; + } + + public String getAuthUser() { + return authUser; + } + + public String getAuthPass() { + return authPass; + } +} http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/4c29c547/ugsync/ldapconfigchecktool/ldapconfigcheck/src/main/java/org/apache/ranger/ldapconfigcheck/LdapConfig.java ---------------------------------------------------------------------- diff --git a/ugsync/ldapconfigchecktool/ldapconfigcheck/src/main/java/org/apache/ranger/ldapconfigcheck/LdapConfig.java b/ugsync/ldapconfigchecktool/ldapconfigcheck/src/main/java/org/apache/ranger/ldapconfigcheck/LdapConfig.java new file mode 100644 index 0000000..a548957 --- /dev/null +++ b/ugsync/ldapconfigchecktool/ldapconfigcheck/src/main/java/org/apache/ranger/ldapconfigcheck/LdapConfig.java @@ -0,0 +1,436 @@ +/* + * 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 java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.util.Properties; + +import org.apache.commons.configuration.ConfigurationException; +import org.apache.commons.lang.NullArgumentException; +import org.apache.commons.configuration.PropertiesConfiguration; + +public class LdapConfig { + + public static final String CONFIG_FILE = "input.properties"; + + private static final String LGSYNC_LDAP_URL = "ranger.usersync.ldap.url"; + + private static final String LGSYNC_LDAP_BIND_DN = "ranger.usersync.ldap.binddn"; + + private static final String LGSYNC_LDAP_BIND_KEYSTORE = "ranger.usersync.credstore.filename"; + + private static final String LGSYNC_LDAP_BIND_ALIAS = "ranger.usersync.ldap.bindalias"; + + private static final String LGSYNC_LDAP_BIND_PASSWORD = "ranger.usersync.ldap.ldapbindpassword"; + + private static final String LGSYNC_LDAP_AUTHENTICATION_MECHANISM = "ranger.usersync.ldap.authentication.mechanism"; + private static final String DEFAULT_AUTHENTICATION_MECHANISM = "simple"; + + private static final String LGSYNC_SEARCH_BASE = "ranger.usersync.ldap.searchBase"; + + private static final String LGSYNC_USER_SEARCH_BASE = "ranger.usersync.ldap.user.searchbase"; + + private static final String LGSYNC_USER_SEARCH_SCOPE = "ranger.usersync.ldap.user.searchscope"; + + private static final String LGSYNC_USER_OBJECT_CLASS = "ranger.usersync.ldap.user.objectclass"; + + private static final String LGSYNC_USER_SEARCH_FILTER = "ranger.usersync.ldap.user.searchfilter"; + + private static final String LGSYNC_USER_NAME_ATTRIBUTE = "ranger.usersync.ldap.user.nameattribute"; + + private static final String LGSYNC_USER_GROUP_NAME_ATTRIBUTE = "ranger.usersync.ldap.user.groupnameattribute"; + + public static final String UGSYNC_LOWER_CASE_CONVERSION_VALUE = "lower"; + + private static final String UGSYNC_USERNAME_CASE_CONVERSION_PARAM = "ranger.usersync.ldap.username.caseconversion"; + private static final String DEFAULT_UGSYNC_USERNAME_CASE_CONVERSION_VALUE = UGSYNC_LOWER_CASE_CONVERSION_VALUE; + + private static final String UGSYNC_GROUPNAME_CASE_CONVERSION_PARAM = "ranger.usersync.ldap.groupname.caseconversion"; + private static final String DEFAULT_UGSYNC_GROUPNAME_CASE_CONVERSION_VALUE = UGSYNC_LOWER_CASE_CONVERSION_VALUE; + + + private static final String LGSYNC_PAGED_RESULTS_ENABLED = "ranger.usersync.pagedresultsenabled"; + private static final boolean DEFAULT_LGSYNC_PAGED_RESULTS_ENABLED = true; + + private static final String LGSYNC_PAGED_RESULTS_SIZE = "ranger.usersync.pagedresultssize"; + private static final int DEFAULT_LGSYNC_PAGED_RESULTS_SIZE = 500; + + private static final String LGSYNC_GROUP_SEARCH_ENABLED = "ranger.usersync.group.searchenabled"; + private static final boolean DEFAULT_LGSYNC_GROUP_SEARCH_ENABLED = false; + + private static final String LGSYNC_GROUP_USER_MAP_SYNC_ENABLED = "ranger.usersync.group.usermapsyncenabled"; + private static final boolean DEFAULT_LGSYNC_GROUP_USER_MAP_SYNC_ENABLED = false; + + private static final String LGSYNC_GROUP_SEARCH_BASE = "ranger.usersync.group.searchbase"; + + private static final String LGSYNC_GROUP_SEARCH_SCOPE = "ranger.usersync.group.searchscope"; + + private static final String LGSYNC_GROUP_OBJECT_CLASS = "ranger.usersync.group.objectclass"; + + private static final String LGSYNC_GROUP_SEARCH_FILTER = "ranger.usersync.group.searchfilter"; + + private static final String LGSYNC_GROUP_NAME_ATTRIBUTE = "ranger.usersync.group.nameattribute"; + + private static final String LGSYNC_GROUP_MEMBER_ATTRIBUTE_NAME = "ranger.usersync.group.memberattributename"; + + //Authentication relate properties + private static final String AUTHENTICATION_METHOD = "ranger.authentication.method"; + private static final String AD_DOMAIN = "ranger.ldap.ad.domain"; + private static final String USER_DN_PATTERN = "ranger.ldap.user.dnpattern"; + private static final String GROUP_ROLE_ATTRIBUTE = "ranger.ldap.group.roleattribute"; + private static final String GROUP_SEARCH_BASE = "ranger.ldap.group.searchbase"; + private static final String GROUP_SEARCH_FILTER = "ranger.ldap.group.searchfilter"; + private static final String AUTH_USERNAME = "ranger.admin.auth.sampleuser"; + private static final String AUTH_PASSWORD = "ranger.admin.auth.samplepassword"; + + + private Properties prop = new Properties(); + + + public LdapConfig(String configFile) { + init(configFile); + } + + private void init(String configFile) { + readConfigFile(configFile); + } + + private void readConfigFile(String fileName) { + try { + InputStream in = getFileInputStream(fileName); + if (in != null) { + try { + System.out.println("Reading ldap properties from " + fileName); + prop.load(in); + + } finally { + try { + in.close(); + } catch (IOException ioe) { + // Ignore IOE when closing stream + System.out.println(ioe); + } + } + } + } catch (Throwable e) { + throw new RuntimeException("Unable to load configuration file [" + fileName + "]", e); + } + } + + + /*private InputStream getFileInputStream(String path) throws FileNotFoundException { + + InputStream ret = null; + + File f = new File(path); + + if (f.exists()) { + ret = new FileInputStream(f); + } + + return ret; + }*/ + + private InputStream getFileInputStream(String path) throws FileNotFoundException { + + InputStream ret = null; + + File f = new File(path); + + if (f.exists()) { + ret = new FileInputStream(f); + } else { + ret = getClass().getResourceAsStream(path); + + if (ret == null) { + if (! path.startsWith("/")) { + ret = getClass().getResourceAsStream("/" + path); + } + } + + if (ret == null) { + ret = ClassLoader.getSystemClassLoader().getResourceAsStream(path) ; + if (ret == null) { + if (! path.startsWith("/")) { + ret = ClassLoader.getSystemResourceAsStream("/" + path); + } + } + } + } + + return ret; + } + + public String getLdapUrl() throws Throwable { + String val = prop.getProperty(LGSYNC_LDAP_URL); + if (val == null || val.trim().isEmpty()) { + throw new NullArgumentException(LGSYNC_LDAP_URL); + } + return val; + } + + + public String getLdapBindDn() throws Throwable { + String val = prop.getProperty(LGSYNC_LDAP_BIND_DN); + if (val == null || val.trim().isEmpty()) { + throw new NullArgumentException(LGSYNC_LDAP_BIND_DN); + } + return val; + } + + + public String getLdapBindPassword() { + //update credential from keystore + if (prop == null) { + return null; + } + return prop.getProperty(LGSYNC_LDAP_BIND_PASSWORD); + } + + + public String getLdapAuthenticationMechanism() { + String val = prop.getProperty(LGSYNC_LDAP_AUTHENTICATION_MECHANISM); + if (val == null || val.trim().isEmpty()) { + return DEFAULT_AUTHENTICATION_MECHANISM; + } + return val; + } + + + public String getUserSearchBase() { + String val = prop.getProperty(LGSYNC_USER_SEARCH_BASE); + if (val == null || val.trim().isEmpty()) { + val = getSearchBase(); + } + return val; + } + + + public int getUserSearchScope() { + String val = prop.getProperty(LGSYNC_USER_SEARCH_SCOPE); + if (val == null || val.trim().isEmpty()) { + return 2; //subtree scope + } + + val = val.trim().toLowerCase(); + if (val.equals("0") || val.startsWith("base")) { + return 0; // object scope + } else if (val.equals("1") || val.startsWith("one")) { + return 1; // one level scope + } else { + return 2; // subtree scope + } + } + + + public String getUserObjectClass() { + String val = prop.getProperty(LGSYNC_USER_OBJECT_CLASS); + return val; + } + + public String getUserSearchFilter() { + return prop.getProperty(LGSYNC_USER_SEARCH_FILTER); + } + + + public String getUserNameAttribute() { + String val = prop.getProperty(LGSYNC_USER_NAME_ATTRIBUTE); + return val; + } + + public String getUserGroupNameAttribute() { + String val = prop.getProperty(LGSYNC_USER_GROUP_NAME_ATTRIBUTE); + return val; + } + + public String getUserNameCaseConversion() { + String ret = prop.getProperty(UGSYNC_USERNAME_CASE_CONVERSION_PARAM, DEFAULT_UGSYNC_USERNAME_CASE_CONVERSION_VALUE); + return ret.trim().toLowerCase(); + } + + public String getGroupNameCaseConversion() { + String ret = prop.getProperty(UGSYNC_GROUPNAME_CASE_CONVERSION_PARAM, DEFAULT_UGSYNC_GROUPNAME_CASE_CONVERSION_VALUE); + return ret.trim().toLowerCase(); + } + + public String getSearchBase() { + return prop.getProperty(LGSYNC_SEARCH_BASE); + } + + public boolean isPagedResultsEnabled() { + boolean pagedResultsEnabled; + String val = prop.getProperty(LGSYNC_PAGED_RESULTS_ENABLED); + if (val == null || val.trim().isEmpty()) { + pagedResultsEnabled = DEFAULT_LGSYNC_PAGED_RESULTS_ENABLED; + } else { + pagedResultsEnabled = Boolean.valueOf(val); + } + return pagedResultsEnabled; + } + + public int getPagedResultsSize() { + int pagedResultsSize; + String val = prop.getProperty(LGSYNC_PAGED_RESULTS_SIZE); + if (val == null || val.trim().isEmpty()) { + pagedResultsSize = DEFAULT_LGSYNC_PAGED_RESULTS_SIZE; + } else { + pagedResultsSize = Integer.parseInt(val); + } + if (pagedResultsSize < 1) { + pagedResultsSize = DEFAULT_LGSYNC_PAGED_RESULTS_SIZE; + } + return pagedResultsSize; + } + + public boolean isGroupSearchEnabled() { + boolean groupSearchEnabled; + String val = prop.getProperty(LGSYNC_GROUP_SEARCH_ENABLED); + if (val == null || val.trim().isEmpty()) { + groupSearchEnabled = DEFAULT_LGSYNC_GROUP_SEARCH_ENABLED; + } else { + groupSearchEnabled = Boolean.valueOf(val); + } + return groupSearchEnabled; + } + + public boolean isGroupUserMapSyncEnabled() { + boolean groupUserMapSyncEnabled; + String val = prop.getProperty(LGSYNC_GROUP_USER_MAP_SYNC_ENABLED); + if (val == null || val.trim().isEmpty()) { + groupUserMapSyncEnabled = DEFAULT_LGSYNC_GROUP_USER_MAP_SYNC_ENABLED; + } else { + groupUserMapSyncEnabled = Boolean.valueOf(val); + } + return groupUserMapSyncEnabled; + } + + public String getGroupSearchBase() { + String val = prop.getProperty(LGSYNC_GROUP_SEARCH_BASE); + return val; + } + + public int getGroupSearchScope() { + String val = prop.getProperty(LGSYNC_GROUP_SEARCH_SCOPE); + if (val == null || val.trim().isEmpty()) { + return 2; //subtree scope + } + + val = val.trim().toLowerCase(); + if (val.equals("0") || val.startsWith("base")) { + return 0; // object scope + } else if (val.equals("1") || val.startsWith("one")) { + return 1; // one level scope + } else { + return 2; // subtree scope + } + } + + public String getGroupObjectClass() { + String val = prop.getProperty(LGSYNC_GROUP_OBJECT_CLASS); + return val; + } + + public String getGroupSearchFilter() { + return prop.getProperty(LGSYNC_GROUP_SEARCH_FILTER); + } + + public String getUserGroupMemberAttributeName() { + String val = prop.getProperty(LGSYNC_GROUP_MEMBER_ATTRIBUTE_NAME); + return val; + } + + public String getGroupNameAttribute() { + String val = prop.getProperty(LGSYNC_GROUP_NAME_ATTRIBUTE); + return val; + } + + public String getAuthenticationMethod() { + String val = prop.getProperty(AUTHENTICATION_METHOD); + return val; + } + + public String getAdDomain() { + String val = prop.getProperty(AD_DOMAIN); + return val; + } + + public String getUserDnPattern() { + String val = prop.getProperty(USER_DN_PATTERN); + return val; + } + + public String getGroupRoleAttribute() { + String val = prop.getProperty(GROUP_ROLE_ATTRIBUTE); + return val; + } + + public String getAuthGroupSearchBase() { + String val = prop.getProperty(GROUP_SEARCH_BASE); + return val; + } + + public String getAuthGroupSearchFilter() { + String val = prop.getProperty(GROUP_SEARCH_FILTER); + return val; + } + + public String getAuthUsername() { + return prop.getProperty(AUTH_USERNAME); + } + + public String getAuthPassword() { + return prop.getProperty(AUTH_PASSWORD); + } + + public void updateInputPropFile(String ldapUrl, String bindDn, String bindPassword, + String userSearchBase, String userSearchFilter, + String authUser, String authPass) { + try { + PropertiesConfiguration config = new PropertiesConfiguration(CONFIG_FILE); + // Update properties in memory and update the file as well + prop.setProperty(LGSYNC_LDAP_URL, ldapUrl); + prop.setProperty(LGSYNC_LDAP_BIND_DN, bindDn); + prop.setProperty(LGSYNC_LDAP_BIND_PASSWORD, bindPassword); + prop.setProperty(LGSYNC_USER_SEARCH_BASE, userSearchBase); + prop.setProperty(LGSYNC_USER_SEARCH_FILTER, userSearchFilter); + prop.setProperty(AUTH_USERNAME, authUser); + prop.setProperty(AUTH_PASSWORD, authPass); + config.setProperty(LGSYNC_LDAP_URL, ldapUrl); + config.setProperty(LGSYNC_LDAP_BIND_DN, bindDn); + config.setProperty(LGSYNC_LDAP_BIND_PASSWORD, bindPassword); + config.setProperty(LGSYNC_USER_SEARCH_BASE, userSearchBase); + config.setProperty(LGSYNC_USER_SEARCH_FILTER, userSearchFilter); + config.setProperty(AUTH_USERNAME, authUser); + config.setProperty(AUTH_PASSWORD, authPass); + config.save(); + } catch (ConfigurationException e) { + System.out.println("Failed to update " + CONFIG_FILE + ": " + e); + } + } +} + + + + + http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/4c29c547/ugsync/ldapconfigchecktool/ldapconfigcheck/src/main/java/org/apache/ranger/ldapconfigcheck/LdapConfigCheckMain.java ---------------------------------------------------------------------- diff --git a/ugsync/ldapconfigchecktool/ldapconfigcheck/src/main/java/org/apache/ranger/ldapconfigcheck/LdapConfigCheckMain.java b/ugsync/ldapconfigchecktool/ldapconfigcheck/src/main/java/org/apache/ranger/ldapconfigcheck/LdapConfigCheckMain.java new file mode 100644 index 0000000..ad56b2e --- /dev/null +++ b/ugsync/ldapconfigchecktool/ldapconfigcheck/src/main/java/org/apache/ranger/ldapconfigcheck/LdapConfigCheckMain.java @@ -0,0 +1,241 @@ +/* + * 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.Context; +import javax.naming.NamingException; +import javax.naming.ldap.Control; +import javax.naming.ldap.InitialLdapContext; +import javax.naming.ldap.LdapContext; +import javax.naming.ldap.PagedResultsControl; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.PrintStream; +import java.util.Properties; + +import org.apache.commons.lang.NullArgumentException; + +public class LdapConfigCheckMain { + + private static final String LOG_FILE = "ldapConfigCheck.log"; + private static final String AMBARI_PROPERTIES = "ambari.properties"; + private static final String INSTALL_PROPERTIES = "install.properties"; + + public static void main(String[] args) { + + CommandLineOptions cli = new CommandLineOptions(args); + cli.parse(); + String inFileName = cli.getInput(); + String outputDir = cli.getOutput(); + if (!outputDir.endsWith("/")) { + outputDir = outputDir.concat("/"); + } + + LdapConfig config = new LdapConfig(inFileName); + if (cli.getLdapUrl() != null && !cli.getLdapUrl().isEmpty()) { + config.updateInputPropFile(cli.getLdapUrl(), cli.getBindDn(), cli.getBindPassword(), + cli.getUserSearchBase(), cli.getUserSearchFilter(), cli.getAuthUser(), cli.getAuthPass()); + } + + PrintStream logFile = null; + PrintStream ambariProps = null; + PrintStream installProps = null; + LdapContext ldapContext; + + try { + logFile = new PrintStream(new File(outputDir + LOG_FILE)); + ambariProps = new PrintStream(new File(outputDir + AMBARI_PROPERTIES)); + installProps = new PrintStream(new File(outputDir + INSTALL_PROPERTIES)); + + UserSync userSyncObj = new UserSync(config, logFile, ambariProps, installProps); + + String bindDn = config.getLdapBindDn(); + + Properties env = new Properties(); + env.put(Context.INITIAL_CONTEXT_FACTORY, + "com.sun.jndi.ldap.LdapCtxFactory"); + env.put(Context.PROVIDER_URL, config.getLdapUrl()); + env.put(Context.SECURITY_PRINCIPAL, bindDn); + env.put(Context.SECURITY_CREDENTIALS, config.getLdapBindPassword()); + env.put(Context.SECURITY_AUTHENTICATION, config.getLdapAuthenticationMechanism()); + env.put(Context.REFERRAL, "follow"); + + ldapContext = new InitialLdapContext(env, null); + + if (config.isPagedResultsEnabled()) { + ldapContext.setRequestControls(new Control[]{ + new PagedResultsControl(config.getPagedResultsSize(), Control.CRITICAL) }); + } + + String retrieveValues = "all"; + + if (cli.getDiscoverProperties() != null) { + retrieveValues = cli.getDiscoverProperties(); + if (cli.getDiscoverProperties().equalsIgnoreCase("users")) { + userSyncObj.findUserProperties(ldapContext); + } else if (cli.getDiscoverProperties().equalsIgnoreCase("groups")) { + userSyncObj.findGroupProperties(ldapContext); + } else { + findAllUserSyncProperties(ldapContext, userSyncObj); + } + }else if (cli.getRetrieveValues() != null){ + retrieveValues = cli.getRetrieveValues(); + + } else { + cli.help(); + } + + if (cli.isAuthEnabled()) { + authenticate(userSyncObj, config, logFile, ambariProps, installProps); + } + + retrieveUsersGroups(ldapContext, userSyncObj, retrieveValues); + + if (ldapContext != null) { + ldapContext.close(); + } + + } catch (FileNotFoundException fe) { + System.out.println(fe.getMessage()); + } catch (IOException ioe) { + logFile.println("ERROR: Failed while setting the paged results controls\n" + ioe); + } catch (NamingException ne) { + System.out.println("ERROR: Failed to perfom ldap bind. Please verify values for " + + "ranger.usersync.ldap.binddn and ranger.usersync.ldap.ldapbindpassword\n" + ne); + } catch (Throwable t) { + if (logFile != null) { + logFile.println("ERROR: Connection failed: " + t.getMessage()); + } else { + System.out.println("ERROR: Connection failed: " + t.getMessage()); + } + } finally { + if (logFile != null) { + logFile.close(); + } + if (ambariProps != null) { + ambariProps.close(); + } + if (installProps != null) { + installProps.close(); + } + } + } + + private static void findAllUserSyncProperties(LdapContext ldapContext, UserSync userSyncObj) throws Throwable { + + userSyncObj.findUserProperties(ldapContext); + userSyncObj.findGroupProperties(ldapContext); + } + + private static void authenticate(UserSync userSyncObj, LdapConfig config, + PrintStream logFile, PrintStream ambariProps, + PrintStream installProps) throws Throwable{ + AuthenticationCheck auth = new AuthenticationCheck(config.getLdapUrl(), userSyncObj, logFile, ambariProps, installProps); + + auth.discoverAuthProperties(); + + String msg; + if (config.getAuthUsername() == null || config.getAuthUsername().isEmpty()) { + msg = "ranger.admin.auth.sampleuser "; + throw new NullArgumentException(msg); + } + + if (config.getAuthPassword() == null || config.getAuthPassword().isEmpty()) { + msg = "ranger.admin.auth.samplepassword "; + throw new NullArgumentException(msg); + } + + if (auth.isAuthenticated(config.getLdapUrl(), config.getLdapBindDn(), config.getLdapBindPassword(), + config.getAuthUsername(), config.getAuthPassword())) { + logFile.println("INFO: Authentication verified successfully"); + } else { + logFile.println("ERROR: Failed to authenticate " + config.getAuthUsername()); + } + } + + private static void retrieveUsersGroups(LdapContext ldapContext, UserSync userSyncObj, + String retrieve) throws Throwable { + String msg; + if (retrieve == null || userSyncObj == null || ldapContext == null) { + msg = "Input validation failed while retrieving Users or Groups"; + throw new NullArgumentException(msg); + } + + if (retrieve.equalsIgnoreCase("users")) { + retrieveUsers(ldapContext, userSyncObj); + } else if (retrieve.equalsIgnoreCase("groups")){ + retrieveGroups(ldapContext, userSyncObj); + } else { + // retrieve both + retrieveUsers(ldapContext, userSyncObj); + retrieveGroups(ldapContext, userSyncObj); + } + } + + private static void retrieveUsers(LdapContext ldapContext, UserSync userSyncObj) throws Throwable { + String msg; + if (userSyncObj.getUserNameAttribute() == null || userSyncObj.getUserNameAttribute().isEmpty()) { + msg = "ranger.usersync.ldap.user.nameattribute "; + throw new NullArgumentException(msg); + } + if (userSyncObj.getUserObjClassName() == null || userSyncObj.getUserObjClassName().isEmpty()) { + msg = "ranger.usersync.ldap.user.objectclass "; + throw new NullArgumentException(msg); + } + if (userSyncObj.getUserGroupMemberName() == null || userSyncObj.getUserGroupMemberName().isEmpty()) { + msg = "ranger.usersync.ldap.user.groupnameattribute "; + throw new NullArgumentException(msg); + } + if ((userSyncObj.getUserSearchBase() == null || userSyncObj.getUserSearchBase().isEmpty()) && + (userSyncObj.getSearchBase() == null || userSyncObj.getSearchBase().isEmpty())) { + msg = "ranger.usersync.ldap.user.searchbase and " + + "ranger.usersync.ldap.searchBase "; + throw new NullArgumentException(msg); + } + userSyncObj.getAllUsers(ldapContext); + } + + private static void retrieveGroups(LdapContext ldapContext, UserSync userSyncObj) throws Throwable { + String msg; + if (userSyncObj.getGroupNameAttrName() == null || userSyncObj.getGroupNameAttrName().isEmpty()) { + msg = "ranger.usersync.group.nameattribute "; + throw new NullArgumentException(msg); + } + if (userSyncObj.getGroupObjClassName() == null || userSyncObj.getGroupObjClassName().isEmpty()) { + msg = "ranger.usersync.group.objectclass "; + throw new NullArgumentException(msg); + } + if (userSyncObj.getUserGroupMemberName() == null || userSyncObj.getUserGroupMemberName().isEmpty()) { + msg = "ranger.usersync.group.memberattributename "; + throw new NullArgumentException(msg); + } + if ((userSyncObj.getGroupSearchBase() == null || userSyncObj.getGroupSearchBase().isEmpty()) && + (userSyncObj.getSearchBase() == null || userSyncObj.getSearchBase().isEmpty())) { + msg = "ranger.usersync.group.searchbase and " + + "ranger.usersync.ldap.searchBase "; + throw new NullArgumentException(msg); + } + userSyncObj.getAllGroups(ldapContext); + } + + +} +