简体   繁体   中英

Query LDAP server using System.DirectoryServices.AccountManagement

I'm trying to run a query on LDAP, but I get exception UnauthorizedAccessException @ new PrincipalSearcher(qbeUser). (see code below)

I don't understand why the application doesn't have access to run this query as when I run ldapsearch command line tool it works fine.

        using(PrincipalContext ctx = new PrincipalContext(ContextType.Machine, "machineName"))
        {
            using(UserPrincipal qbeUser = new UserPrincipal(ctx))
            {
                using (PrincipalSearcher srch = new PrincipalSearcher(qbeUser))
                {
                    foreach (var found in srch.FindAll())
                    {
                        var user = (UserPrincipal)found;
                        Console.WriteLine(user.GivenName + " " + user.Surname +  " " + user.EmailAddress);
                    }
                }
            }
        }

Here is an IBM technote on how to collect debug data for LDAP on the Domino server side. I would suggest using the LDAPDEBUG=7 setting right from the get-go, and comparing the console log output on the server for your ldapsearch query and your program's query.

What you probably need to pay attention to is the authentication during the bind operation. You haven't mentioned whether you passed any authentication info in the ldapsearch command line (-D and -w arguments), and you haven't said anything about SSO -- and I'm not even sure if Domino LDAP participates in any SSO. The data logged on the server should help clarify what (if any) identity your query is using for binding. Normal settings on the Domino Directory would protect against anonymous queries, and I think it also restricts the attributes available when a user without Editor rights (or above) queries other user accounts.

If you do not have administrative rights for the server, or a test server on which you can duplicate the problem, you will have to coordinate with the actual admins. You don't want to leave the LDAPDEBUG setting turned on longer than necessary.

Please see code below:

        using(PrincipalContext ctx = new PrincipalContext(ContextType.Domain, "DOMAINNAME"))
        {
            using(UserPrincipal qbeUser = new UserPrincipal(ctx))
            {
                using (PrincipalSearcher srch = new PrincipalSearcher(qbeUser))
                {
                    foreach (var found in srch.FindAll())
                    {
                        var user = (UserPrincipal)found;
                        Console.WriteLine(user.GivenName + " " + user.Surname +  " " + user.EmailAddress);
                    }
                }
            }
        }

If I do it like this it works fine, but I cannot specify the server name. Also not sure if it returns same results as the command line.

I tried using ValidateCredentials to check if the validation passes using my credential (using ContextType.Machine) but instead of returning true or false it throws the UnauthorizedAccessException.

I've tried accessing the domino server using a different method in .NET, unfortunately this one didn't worked either. (it thrown DirectoryServicesCOMException (A protocol error occurrred).

        // create your "base" - the ou "formeremployees"
        DirectoryEntry formerEmployeeOU = new DirectoryEntry("LDAP://HOSTNAME");

        // create a searcher to find objects inside this container
        DirectorySearcher feSearcher = new DirectorySearcher(formerEmployeeOU);

        // define a standard ldap filter for what you search for - here "users"    
        feSearcher.Filter = "objectClass=*";

        // define the properties you want to have returned by the searcher
        feSearcher.PropertiesToLoad.Add("givenname");
        feSearcher.PropertiesToLoad.Add("sn");
        feSearcher.PropertiesToLoad.Add("mail");
        feSearcher.PropertiesToLoad.Add("memberOf");

        // search and iterate over results
        foreach (SearchResult sr in feSearcher.FindAll())
        {
            //do something
        }

        return;

The quick solution for me is to run the ldapsearch command line tool.

        // Start the child process.
        Process p = new Process();
        // Redirect the output stream of the child process.
        p.StartInfo.UseShellExecute = false;
        p.StartInfo.RedirectStandardOutput = true;
        p.StartInfo.FileName = "ldapsearch";
        p.StartInfo.Arguments = "-L -h hostname \"objectClass=*\" givenname sn mail";
        p.Start();
        // Do not wait for the child process to exit before
        // reading to the end of its redirected stream.
        // p.WaitForExit();
        // Read the output stream first and then wait.
        string output = p.StandardOutput.ReadToEnd();
        p.WaitForExit();

        System.IO.File.WriteAllText(@"output.txt", output);
        return;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM