Repository: ambari Updated Branches: refs/heads/trunk e59405796 -> 171f8b8e0
AMBARI-11362. Kerberos: Creating principals in AD when special characters are involved causes failures (rlevas) Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/171f8b8e Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/171f8b8e Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/171f8b8e Branch: refs/heads/trunk Commit: 171f8b8e0599c7d65a3857be0333dcdf79b40903 Parents: e594057 Author: Robert Levas <[email protected]> Authored: Mon May 25 09:44:58 2015 -0400 Committer: Robert Levas <[email protected]> Committed: Mon May 25 09:45:09 2015 -0400 ---------------------------------------------------------------------- .../kerberos/ADKerberosOperationHandler.java | 92 +++++--------------- .../ADKerberosOperationHandlerTest.java | 15 ---- 2 files changed, 24 insertions(+), 83 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/171f8b8e/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/ADKerberosOperationHandler.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/ADKerberosOperationHandler.java b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/ADKerberosOperationHandler.java index 38a7563..7f82cfd 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/ADKerberosOperationHandler.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/ADKerberosOperationHandler.java @@ -30,8 +30,19 @@ import org.apache.velocity.exception.MethodInvocationException; import org.apache.velocity.exception.ParseErrorException; import org.apache.velocity.exception.ResourceNotFoundException; -import javax.naming.*; -import javax.naming.directory.*; +import javax.naming.AuthenticationException; +import javax.naming.CommunicationException; +import javax.naming.Context; +import javax.naming.NamingEnumeration; +import javax.naming.NamingException; +import javax.naming.directory.Attribute; +import javax.naming.directory.Attributes; +import javax.naming.directory.BasicAttribute; +import javax.naming.directory.BasicAttributes; +import javax.naming.directory.DirContext; +import javax.naming.directory.ModificationItem; +import javax.naming.directory.SearchControls; +import javax.naming.directory.SearchResult; import javax.naming.ldap.Control; import javax.naming.ldap.InitialLdapContext; import javax.naming.ldap.LdapContext; @@ -41,13 +52,9 @@ import java.io.StringWriter; import java.io.UnsupportedEncodingException; import java.lang.reflect.Type; import java.util.Collection; -import java.util.Collections; import java.util.HashMap; -import java.util.HashSet; -import java.util.List; import java.util.Map; import java.util.Properties; -import java.util.Set; /** * Implementation of <code>KerberosOperationHandler</code> to created principal in Active Directory @@ -59,34 +66,6 @@ public class ADKerberosOperationHandler extends KerberosOperationHandler { private static final String LDAP_CONTEXT_FACTORY_CLASS = "com.sun.jndi.ldap.LdapCtxFactory"; /** - * A Set of special characters that need to be escaped if they exist within a value in a - * Distinguished Name. - * - * See http://social.technet.microsoft.com/wiki/contents/articles/5312.active-directory-characters-to-escape.aspx - */ - private static final Set<Character> SPECIAL_DN_CHARACTERS = Collections.unmodifiableSet( - new HashSet<Character>() { - { - add('/'); - add(','); - add('\\'); - add('#'); - add('+'); - add('<'); - add('>'); - add(';'); - add('"'); - add('='); - add(' '); - } - }); - - /** - * The character to use to escape a special character within a value in a Distinguished Name - */ - private static final Character DN_ESCAPE_CHARACTER = '\\'; - - /** * A String containing the URL for the LDAP interface for the relevant Active Directory */ private String ldapUrl = null; @@ -302,12 +281,16 @@ public class ADKerberosOperationHandler extends KerberosOperationHandler { attribute.add(object); } } else { - attribute.add(value); - if ("cn".equals(key) && (value != null)) { cn = value.toString(); + } else if ("sAMAccountName".equals(key) && (value != null)) { + // Replace the following _illegal_ characters: [ ] : ; | = + * ? < > / , (space) \ + value = value.toString().replaceAll("\\[|\\]|\\:|\\;|\\||\\=|\\+|\\*|\\?|\\<|\\>|\\/|\\\\|\\,|\\s", "_"); } + + attribute.add(value); } + attributes.put(attribute); } } @@ -316,8 +299,11 @@ public class ADKerberosOperationHandler extends KerberosOperationHandler { if (cn == null) { cn = deconstructedPrincipal.getNormalizedPrincipal(); } + try { - Name name = new CompositeName().add(String.format("cn=%s,%s", cn, principalContainerDn)); + Rdn rdn = new Rdn("cn", cn); + LdapName name = new LdapName(principalContainerDn); + name.add(name.size(), rdn); ldapContext.createSubcontext(name, attributes); } catch (NamingException ne) { throw new KerberosOperationException("Can not create principal : " + principal, ne); @@ -354,7 +340,7 @@ public class ADKerberosOperationHandler extends KerberosOperationHandler { if (dn != null) { ldapContext.modifyAttributes( - escapeDNCharacters(dn), + dn, new ModificationItem[]{ new ModificationItem(DirContext.REPLACE_ATTRIBUTE, new BasicAttribute("unicodePwd", String.format("\"%s\"", password).getBytes("UTF-16LE"))) } @@ -581,34 +567,4 @@ public class ADKerberosOperationHandler extends KerberosOperationHandler { return dn; } - - /** - * Iterates through the characters of the given distinguished name to escape special characters - * - * @param dn the distinguished name to process - * @return the distinguished name with escaped characters - * @see #escapeCharacters(String, java.util.Set, Character) - */ - protected String escapeDNCharacters(String dn) throws InvalidNameException { - if ((dn == null) || dn.isEmpty()) { - return dn; - } else { - LdapName name = new LdapName(dn); - List<Rdn> rdns = name.getRdns(); - - if ((rdns == null) || rdns.isEmpty()) { - throw new InvalidNameException(String.format("One or more RDNs are expected for a DN of %s", dn)); - } - - StringBuilder builder = new StringBuilder(); - for (Rdn rdn : rdns) { - builder.insert(0, - String.format(",%s=%s", - rdn.getType(), - escapeCharacters((String) rdn.getValue(), SPECIAL_DN_CHARACTERS, DN_ESCAPE_CHARACTER))); - } - - return builder.substring(1); - } - } } http://git-wip-us.apache.org/repos/asf/ambari/blob/171f8b8e/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/ADKerberosOperationHandlerTest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/ADKerberosOperationHandlerTest.java b/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/ADKerberosOperationHandlerTest.java index 48bf473..d7fffb2 100644 --- a/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/ADKerberosOperationHandlerTest.java +++ b/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/ADKerberosOperationHandlerTest.java @@ -441,21 +441,6 @@ public class ADKerberosOperationHandlerTest extends KerberosOperationHandlerTest } - @Test - public void testEscapeDistinguishedName() throws NoSuchMethodException, InvalidNameException { - ADKerberosOperationHandler handler = new ADKerberosOperationHandler(); - - try { - handler.escapeDNCharacters("nn/c6501.ambari.apache.org"); - Assert.fail("Expected InvalidNameException"); - } catch (InvalidNameException e) { - // This is expected - } - - Assert.assertEquals("CN=nn\\/c6501.ambari.apache.org,OU=HDP,DC=HDP01,DC=LOCAL", - handler.escapeDNCharacters("CN=nn/c6501.ambari.apache.org,OU=HDP,DC=HDP01,DC=LOCAL")); - } - /** * Implementation to illustrate the use of operations on this class *
