Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# Active Directory, Login in a specific OU

I want to login in a only specific OU, but not in previous OU.

My parent function is:

    if (Autentificado("LDAP://localhost/DC=ic,DC=enterprise,DC=us", user, pass, "cn=SpecificPeople,ou=Users,ou=Aplications,dc=ic,dc=enterprise,dc=us") != "")
    {
                    
                    return "OK";
    }

It contains server direction with path, user, pass and a string for the "memberof" filter:

public static string Autentificado(string ldap, string usr, string pwd,string member)
        {
          try
            {
                DirectoryEntry entry = new DirectoryEntry(ldap, usr, pwd);
                DirectorySearcher search = new DirectorySearcher(entry)
                {
                                   
                  Filter = "(&(objectCategory=person)(memberof=" + member + "))"
                
                };
                search.PropertiesToLoad.Add("sn");
                SearchResult result = search.FindOne();
                return result.Properties["sn"][0].ToString();
            }
            catch (DirectoryServicesCOMException cex)
            {
                Console.WriteLine(cex);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
            }
            return "";
           

        }

It return the correct user of "OU=Users", but it return users of others OU or DC. I want that people only can login in the "OU=Users".

Thanks in advance.

UPDATE 1: I think that the problem is with the structure of my LDAP and the filter of the DirectorySearcher:

DC=US
 -DC=enterprise
  -DC=ic
   -OU=Apps
     -OU=1
     -OU=2
     -OU=USERS

If i use: SearchScope.Subtree, it search in all directories.SearchScope.OneLevel, it search in the DC=enterprise or in all OU=Apps (if i'm not mistaken).SearchScope.Base, it search in the DC=US.

I want that the search will be only in the OU=USERS, and not in the others Directories (OU=1, OU=2).

UPDATE 2

My GETUSER funtion is:

DirectoryEntry usercheck = GetUser(user, pass,"LDAP://someIP:389/CN=qualifiers,OU=USERS,OU=Aplications,DC=ic,DC=enterprise,DC=us");

And in the "DirectoryEntry searchRoot", i need to set an user and password for enter in the LDAP. If not, it take me error:

using (DirectoryEntry searchRoot = new DirectoryEntry(rootWeAreLooking,"ic\\"+userName,pass, AuthenticationTypes.None))
            

I see that this could be work, but it search in all directories of OU=Aplications yet.

I think that i need to filter by CN=qualifiers, but i don't know how.

Update 3

I need to try properly, but i think that i do the correct filter:

searcher.Filter = String.Format("(&(objectCategory=person)(memberof=CN=qualifiers,OU=USERS,OU=Aplications,DC=ic,DC=enterprise,DC=us)(sAMAccountName={0}))", userName);
                    
like image 661
Jm.ortega Avatar asked Nov 22 '25 01:11

Jm.ortega


2 Answers

So I just created this code which does the thing you want. I splitted the code into multiple methods, so you can use some singe functions like ValidateUser else where.

  1. Find the user in the AD and the ou (root) you are searching in and make shure he exits
  2. Now that we know that he is allowed to "LOGIN" we are validating his password against AD.
  3. If all went fine, the user is in the OU=USER (in your case) and also the password is correct

    private void TestTheMethods()
    {
        //Search for the user, in the ou "user" 
        DirectoryEntry user = GetUser("FirstName LastName","FullOrganisationUnitPath");
        //Found user?
        if (user == null) { return; }
    
        //ValidateUser
        if (!ValidateUser(user, "userPassword")) { return; }
    }     
    
    public DirectoryEntry GetUser(string userName, string rootWeAreLooking = "")
    {
        DirectoryEntry user = null;
    
        using(DirectoryEntry searchRoot = new DirectoryEntry(rootWeAreLooking))
        using(DirectorySearcher searcher = new DirectorySearcher(searchRoot))
        {
            searcher.Filter = String.Format("(&(objectCategory=person)(cn={0}))",userName);
            //searcher.SearchScope = SearchScope.Subtree;
    
            //SearchScope.Subtree --> Search in all nested OUs
            //SearchScope.OneLevel --> Search in the Ou underneath
            //SearchScope.Base    --> Search in the current OU
    
            search.SearchScope = SearchScope.OneLevel;
    
            SearchResult result = searcher.FindOne();
            if (result == null) { return null; }
    
            //Found user
            return result.GetDirectoryEntry();
        }
    }
    
    public Boolean ValidateUser(DirectoryEntry entry, string pwd)
    {
        Boolean isValid = false;
    
        try
        {
            DirectoryEntry validatedUser = new DirectoryEntry(entry.Path, entry.Name.Remove(0,3), pwd);
            //Check if we can access the Schema
            var Name = validatedEntry.SchemaEntry;
            //User exits, username is correct and password is accepted
            isValid = true;
        }
        catch(DirectoryServicesCOMException ex)
        {
            isValid = false;
            ///User wrong? wrong password?
        }
    
        return isValid;
    }
    
like image 147
C0d1ngJammer Avatar answered Nov 24 '25 14:11

C0d1ngJammer


Finally, I do this filter and works for me:

searcher.Filter = String.Format("(&(objectCategory=person)(memberof=CN=qualifiers,OU=USERS,OU=Aplications,DC=ic,DC=enterprise,DC=us)(sAMAccountName={0}))", userName);

And in my LDAP path, i put the root path directory

DC=ic,DC=enterprise,DC=us
like image 42
Jm.ortega Avatar answered Nov 24 '25 14:11

Jm.ortega



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!