LDAP Connecting with IP address and Port Number

jp2code picture jp2code · Sep 28, 2017 · Viewed 8.1k times · Source

The company I work for has a product that uses Active Directory to enable our product's security features using a library that includes DirectoryEntry and DirectorySearcher components.

If someone is a member of group FOO, they have standard access. If they are a member of FOO-ADMIN, they have Admin rights.

We have a potential client who does not use Active Directory. They have an Apache server running their LDAP, and they have provided this screenshot.

Customer Properties

Above, it looks like I would need to connect to a domain of xxx.xxx.5.101:389 (i.e. DirectoryEntry("LDAP://xxx.xxx.5.101:389")), but how does that "DN or user" field fit with the password?

Are Active Directory components able to do LDAP authentication on an Apache system, or would the code need completely different controls?

Here is some crude code that I have put together:

/// <summary>
/// Untested Method
/// </summary>
/// <param name="hostIp">String (EX: xxx.xxx.5.101)</param>
/// <param name="port">Int (EX: 389)</param>
/// <param name="user">String (EX: cn=danibla,ou=sysdata,ou=townhall,o=toh)</param>
/// <param name="password">String - provided password</param>
/// <param name="groupsLike">String (EX: find all groups like FOO)</param>
/// <returns>String[] array of matching membership groups</returns>
public static String[] GetMemberships(String hostIp, int port, String user, String password, String groupsLike)
{
    var results = new List<String>();
    var path = String.Format("LDAP://{0}:{1}", hostIp, port);
    using (var entry = new DirectoryEntry(path, user, password))
    {
        using (var search = new DirectorySearcher(entry, String.Format("(CN={0}*)", groupsLike)))
        {
            var expression = new Regex("CN=([^,]*),", RegexOptions.Compiled & RegexOptions.IgnoreCase);
            foreach (SearchResult item in search.FindAll())
            {
                var match = expression.Match(item.Path);
                var name = match.Groups[1].Value;
                if (name.StartsWith(groupsLike, StringComparison.OrdinalIgnoreCase))
                {
                    if (!results.Contains(name))
                    {
                        results.Add(name);
                    }
                }
            }
        }
    }
    return results.ToArray();
}

I am bothered by the "path like" parameters they pass in for the "DN or user" field, particularly when it shows them providing a password with it.

We do not have an Apache environment to test this on. Our company does not want me going to this client with a lot of unnecessary questions.

UPDATE:
Still need a way to do this. Starting a bounty. Maybe bringing some attention to this will get me a solution.

currentState

In the screenshot above, the value for username in the code was both cn-mikead,ou=sysdata,ou=townhall,o=toh and separately mikead, both with the same COM Exception at the call to FindAll().

Here is the code I have now.

public static String[] Groups(String domain, int port, String username, int authenticationValue, String startsWith)
{
    String name;
    var results = new List<String>();
    var ldapPath =
        String.IsNullOrEmpty(domain) ? null :
        (0 < port) ?
        String.Format("LDAP://DC={0}:{1}", domain, port) :
        String.Format("LDAP://DC={0}", domain);
    using (var entry = new DirectoryEntry(String.Format("WinNT://{0}/{1}", Environment.UserDomainName, username)))
    {
        name = String.Format("{0}", entry.Properties["fullName"].Value);
    }
    var filter = String.Format("(CN={0}", name);
    var expression = new Regex("CN=([^,]*),", RegexOptions.Compiled & RegexOptions.IgnoreCase);
    using (var entry = new DirectoryEntry(ldapPath))
    {
        entry.AuthenticationType = (AuthenticationTypes)authenticationValue;
        using (var search = new DirectorySearcher(entry) { Filter = filter })
        {
            search.PropertiesToLoad.Add("memberOf");
            try
            {
                foreach (SearchResult item in search.FindAll())
                {
                    foreach (var property in item.Properties["memberOf"])
                    {
                        var name = expression.Match(String.Format("{0}", property)).Groups[1].Value;
                        if (name.StartsWith(startsWith, StringComparison.OrdinalIgnoreCase))
                        {
                            if (!results.Contains(name))
                            {
                                results.Add(name);
                            }
                        }
                    }
                }
            }
            catch (Exception err)
            {
                LogError("Groups", err);
            }
        }
    }
    return results.ToArray();
}

Answer

Switch Case picture Switch Case · Oct 5, 2017

Apache can run LDAP, my advice would be to make sure your client has LDAP configured properly on their server. This could be done in the httpd.conf on their server