Return-Path: X-Original-To: apmail-hive-commits-archive@www.apache.org Delivered-To: apmail-hive-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 4A92A18137 for ; Sat, 19 Sep 2015 02:03:05 +0000 (UTC) Received: (qmail 40176 invoked by uid 500); 19 Sep 2015 02:03:05 -0000 Delivered-To: apmail-hive-commits-archive@hive.apache.org Received: (qmail 40126 invoked by uid 500); 19 Sep 2015 02:03:05 -0000 Mailing-List: contact commits-help@hive.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: hive-dev@hive.apache.org Delivered-To: mailing list commits@hive.apache.org Received: (qmail 40109 invoked by uid 99); 19 Sep 2015 02:03:05 -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, 19 Sep 2015 02:03:05 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id CEB3BE05D3; Sat, 19 Sep 2015 02:03:04 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: ctang@apache.org To: commits@hive.apache.org Message-Id: <2d524c21deb0437a9552eaac49b050ab@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: hive git commit: HIVE-11512: Hive LDAP Authenticator should also support full DN in Authenticate() Naveen Gangam via Chaoyu Tang Date: Sat, 19 Sep 2015 02:03:04 +0000 (UTC) Repository: hive Updated Branches: refs/heads/branch-1 86eebbdef -> c0925634e HIVE-11512: Hive LDAP Authenticator should also support full DN in Authenticate() Naveen Gangam via Chaoyu Tang Project: http://git-wip-us.apache.org/repos/asf/hive/repo Commit: http://git-wip-us.apache.org/repos/asf/hive/commit/c0925634 Tree: http://git-wip-us.apache.org/repos/asf/hive/tree/c0925634 Diff: http://git-wip-us.apache.org/repos/asf/hive/diff/c0925634 Branch: refs/heads/branch-1 Commit: c0925634e4aab7a8ba53da1ecff6fbe7285c4211 Parents: 86eebbd Author: ctang Authored: Fri Sep 18 22:02:22 2015 -0400 Committer: ctang Committed: Fri Sep 18 22:02:22 2015 -0400 ---------------------------------------------------------------------- .../auth/LdapAuthenticationProviderImpl.java | 82 ++++++++++++++++++-- 1 file changed, 76 insertions(+), 6 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/hive/blob/c0925634/service/src/java/org/apache/hive/service/auth/LdapAuthenticationProviderImpl.java ---------------------------------------------------------------------- diff --git a/service/src/java/org/apache/hive/service/auth/LdapAuthenticationProviderImpl.java b/service/src/java/org/apache/hive/service/auth/LdapAuthenticationProviderImpl.java index 0c7cede..b2c4daf 100644 --- a/service/src/java/org/apache/hive/service/auth/LdapAuthenticationProviderImpl.java +++ b/service/src/java/org/apache/hive/service/auth/LdapAuthenticationProviderImpl.java @@ -146,15 +146,28 @@ public class LdapAuthenticationProviderImpl implements PasswdAuthenticationProvi DirContext ctx = null; String userDN = null; + String userName = null; try { // Create initial context ctx = new InitialDirContext(env); + if (isDN(user)) { + userName = extractName(user); + } else { + userName = user; + } + if (userFilter == null && groupFilter == null && customQuery == null) { - userDN = findUserDNByPattern(ctx, user); + if (isDN(user)) { + userDN = findUserDNByDN(ctx, user); + } else { + if (userDN == null) { + userDN = findUserDNByPattern(ctx, user); + } - if (userDN == null) { - userDN = findUserDNByName(ctx, baseDN, user); + if (userDN == null) { + userDN = findUserDNByName(ctx, baseDN, user); + } } // This should not be null because we were allowed to bind with this username @@ -185,7 +198,7 @@ public class LdapAuthenticationProviderImpl implements PasswdAuthenticationProvi boolean success = false; for (String filteredUser : userFilter) { - if (filteredUser.equalsIgnoreCase(user)) { + if (filteredUser.equalsIgnoreCase(userName)) { LOG.debug("User filter partially satisfied"); success = true; break; @@ -198,7 +211,7 @@ public class LdapAuthenticationProviderImpl implements PasswdAuthenticationProvi "of specified list"); } - userDN = findUserDNByPattern(ctx, user); + userDN = findUserDNByPattern(ctx, userName); if (userDN != null) { LOG.info("User filter entirely satisfied"); } else { @@ -214,7 +227,7 @@ public class LdapAuthenticationProviderImpl implements PasswdAuthenticationProvi // if only groupFilter is configured. if (userDN == null) { - userDN = findUserDNByName(ctx, baseDN, user); + userDN = findUserDNByName(ctx, baseDN, userName); } List userGroups = getGroupsForUser(ctx, userDN); @@ -395,6 +408,44 @@ public class LdapAuthenticationProviderImpl implements PasswdAuthenticationProvi return null; } + /** + * This helper method attempts to find a username given a DN. + * Various LDAP implementations have different keys/properties that store this unique userID. + * Active Directory has a "sAMAccountName" that appears reliable,openLDAP uses "uid" + * So the first attempt is to find an entity with objectClass=person||user where + * (uid||sAMAccountName) matches the given username. + * The second attempt is to use CN attribute for wild card matching and then match the + * username in the DN. + * @param ctx DirContext for the LDAP Connection. + * @param baseDN BaseDN for this LDAP directory where the search is to be performed. + * @param userName A unique userid that is to be located in the LDAP. + * @return LDAP DN if the user is found in LDAP, null otherwise. + */ + public static String findUserDNByDN(DirContext ctx, String userDN) + throws NamingException { + if (!isDN(userDN)) { + return null; + } + + String baseDN = extractBaseDN(userDN); + List results = null; + String searchFilter = "(&(|(objectClass=person)(objectClass=user))(" + DN_ATTR + "=" + + userDN + "))"; + + results = findDNByName(ctx, baseDN, searchFilter, 2); + + if (results == null) { + return null; + } + + if(results.size() > 1) { + //make sure there is not another item available, there should be only 1 match + LOG.info("Matched multiple users for the user: " + userDN + ",returning null"); + return null; + } + return userDN; + } + public static List findDNByName(DirContext ctx, String baseDN, String searchString, int limit) throws NamingException { SearchResult searchResult = null; @@ -507,4 +558,23 @@ public class LdapAuthenticationProviderImpl implements PasswdAuthenticationProvi } return list; } + + public static boolean isDN(String name) { + return (name.indexOf("=") > -1); + } + + public static String extractName(String dn) { + if (dn.indexOf("=") > -1) { + return dn.substring(dn.indexOf("=") + 1, dn.indexOf(",")); + } + return dn; + } + + public static String extractBaseDN(String dn) { + if (dn.indexOf(",") > -1) { + return dn.substring(dn.indexOf(",") + 1); + } + return null; + } + }