Search code examples
c#ldapsanitization

How does LdapDistinguishedNameEncode work with the C# DirectoryServices library?


I'm trying to sanitize user input of an OU name for a C# application.

AntiXSS's LdapDistinguishedNameEncode appears to be custom-made for this, but when I try to use this on an OU's name, insert that into a distinguished name, and pass it into a PrincipalContext or DirectoryEntry object I get exceptions that the object cannot be found.

When using an un-sanitized OU name it all works successfully.

Do the AD libraries understand encoded distinguished names? Or is the expectation that LdapDistinguishedNameEncode is meant to be run before OU creation as well as when referencing it later?

Sample code, where ouName is "Bob-Marley" or "dlanod's company" and the dashes and apostrophes get encoded:

        var distinguishedName = $"OU={Encoder.LdapDistinguishedNameEncode(ouName)},DC=sample,DC=net";

        try
        {
            // Create a context for the OU
            var context = new PrincipalContext(ContextType.Domain, _targetedUrl, distinguishedName, ContextOptions.Negotiate | ContextOptions.Signing | ContextOptions.Sealing);
        }
        catch (Exception e)
        {
            _logger.Error(e, "Organization {0} with definition {1} could not be found, exception occurred {2}", ouName, distinguishedName, e);
        }

Solution

  • I did not find a workable approach that still let me use LdapDistinguishedNameEncode .

    The code I adopted was:

            // Reject organization names with illegal or problematic characters (taken from RFC2253).
            // Used instead of Encoder.LdapDistinguishedNameEncode because of an expectation that
            // the creation passes through the same function.
            // https://social.technet.microsoft.com/wiki/contents/articles/5312.active-directory-characters-to-escape.aspx
            char[] illegalChars = {',', '\\', '#', '+', '<', '>', ';', '"', '='};
            if (name.IndexOfAny(illegalChars) >= 0)
            {
                return false;
            }