Active Directory: Does Invalid character escaping

2019-03-04 06:52发布

问题:

I have built a process to extract data from active directory via a C# script component in SSIS. This data needs to be loaded into SQL Server. I am running into problems where the DistinguishedName (DN) and CanonicalName (CN) contain the double quote (") and backslash (\) escape characters (see weblink below).

https://social.technet.microsoft.com/wiki/contents/articles/5312.active-directory-characters-to-escape.aspx

From what I can tell, all escape characters should have a leading backslash (\). Is this correct? I am asking because it appears that I have found instances where this is not true and so I am unable to remove these escape characters, which is causing SSIS import to fail with the error that it cannot find the column delimiter for DN and CN respectively. Note: I have set the double quote (") as a column delimiter in the SSIS connection manager. Is there a way to handle this in code or do I need to have the AD admin fix it?

string strDistinguishedName = objConverter.ConvertToString(searchResult, "distinguishedName").Replace("\"","").Replace("\\"","");

Input1: "CN=SomethingHere “Got Rocks\\\" OtherTextHere,OU=Blah,OU=Bleh,DC=jweezy,DC=com"

Output1: "CN=SomethingHere “Got Rocks OtherTextHere,OU=Blah,OU=Bleh,DC=jweezy,DC=com"

Input2: "CN=SomethingHere2 “Got Gravel" OtherTextHere2,OU=Blah2,OU=Bleh,DC=jweezy,DC=com"

Output2: "CN=SomethingHere2 “Got Gravel" OtherTextHere2,OU=Blah2,OU=Bleh,DC=jweezy,DC=com"

The problem seems to be caused by the lack of escape character, so I believe the inputs should be as follows:

Input1: "CN=SomethingHere \“Got Rocks\" OtherTextHere,OU=Blah,OU=Bleh,DC=jweezy,DC=com"

Input2: "CN=SomethingHere2 \“Got Gravel\" OtherTextHere2,OU=Blah2,OU=Bleh,DC=jweezy,DC=com"

回答1:

When they say that double quotes need to be escaped, they mean the Quotation Mark character: http://www.fileformat.info/info/unicode/char/22/index.htm

In this case:

Input1: "CN=SomethingHere “Got Rocks\\\" OtherTextHere,OU=Blah,OU=Bleh,DC=jweezy,DC=com"

The character you are seeing not escaped () is different. It's the Left Double Quotation Mark: http://www.fileformat.info/info/unicode/char/201C/index.htm

That has no special meaning to AD and so does not need to be escaped.

But this one:

Input2: "CN=SomethingHere2 “Got Gravel" OtherTextHere2,OU=Blah2,OU=Bleh,DC=jweezy,DC=com"

If you copy and pasted that exactly as it is, then I can't comment. The quote after the word "Gravel" should be escaped. Just now, I tried to rename an account and add a quote, and it automatically escaped it in the DN.



回答2:

    /// <summary>
    /// Escapes the LDAP search filter to prevent LDAP injection attacks.
    /// </summary>
    private static string EscapeLdapSearchFilter(string searchFilter)
    {
        StringBuilder escape = new StringBuilder();
        for (int i = 0; i < searchFilter.Length; ++i)
        {
            char current = searchFilter[i];
            switch (current)
            {
                case '\\':
                    escape.Append(@"\5c");
                    break;
                case '/':
                    escape.Append(@"\2f");
                    break;
                case '(':
                    escape.Append(@"\28");
                    break;
                case ')':
                    escape.Append(@"\29");
                    break;
                case '\u0000':
                    escape.Append(@"\00");
                    break;
                case '*':
                    escape.Append(@"\2a");
                    break;
                default:
                    escape.Append(current);
                    break;
            }
        }
        return escape.ToString();
    }

    /// <summary>
    /// When renaming a DirectoryEntry via "DE.Rename(newCN)" 
    /// you will need to escape certain character(s) ... ex. "," to "\,"
    /// </summary>
    private static string EscapeFullNameFilter(string unescapedString)
    {
        StringBuilder escape = new StringBuilder();
        for (int i = 0; i < unescapedString.Length; ++i)
        {
            char current = unescapedString[i];
            switch (current)
            {
                case '\\':
                case ',':
                case ';':
                case '"':
                case '=':
                case '+':
                case '<':
                case '>':
                case '#':
                    escape.Append(@"\"); //We need to show to escape the current char, so we add this before it.
                    escape.Append(current);
                    break;
                default:
                    escape.Append(current);
                    break;
            }
        }
        return escape.ToString();
    }