2010-11-23 4 views
1

J'ai un client qui utilise un service Windows que j'ai écrit qui interroge un serveur LDAP de répertoire actif spécifié pour les utilisateurs dans les groupes spécifiés au sein de ce serveur LDAP. Une fois qu'il trouve un utilisateur, il remplit les informations de l'utilisateur (c'est-à-dire le nom d'utilisateur, le courrier électronique, etc.) et tente de récupérer le domaine de l'utilisateur au sein de ce serveur LDAP.Active Directory: Obtenir RootDSE dans un domaine résidant dans la forêt avec plusieurs racines?

Lorsque j'essaie de récupérer le domaine de l'utilisateur pour ce client spécifique, j'obtiens une exception DirectoryServicesCOMException: Échec d'ouverture de session: nom d'utilisateur inconnu ou mot de passe incorrect. Cette exception est levée lorsque je tente de référencer une propriété sur l'objet RootDSE DirectoryEntry que j'instancie.

Ce client a une forêt à deux racines, configurée comme suit.

Active Directory Domaines et approbations

  • ktregression.com

  • ktregression.root

Je suppose que c'est la question. Y a-t-il un moyen de contourner cela? Un moyen de toujours récupérer le nom netbios d'un objet domaine spécifique sans courir dans cette exception?

Voici quelques exemples de code montrant une configuration du serveur AD test, comme indiqué précédemment:

 string domainNameLdap = "dc=tempe,dc=ktregression,dc=com"; 

     DirectoryEntry RootDSE = new DirectoryEntry (@"LDAP://10.32.16.6/RootDSE"); 
     DirectoryEntry servers2 = new DirectoryEntry (@"LDAP://cn=Partitions," + RootDSE.Properties["configurationNamingContext"].Value); //*****THIS IS WHERE THE EXCEPTION IS THROWN******** 

     //Iterate through the cross references collection in the Partitions container 
     DirectorySearcher clsDS = new DirectorySearcher(servers2); 
     clsDS.Filter = "(&(objectCategory=crossRef)(ncName=" + domainNameLdap + "))"; 
     clsDS.SearchScope = SearchScope.Subtree; 
     clsDS.PropertiesToLoad.Add("nETBIOSName"); 

     List<string> bnames = new List<string>(); 

     foreach (SearchResult result in clsDS.FindAll()) 
      bnames.Add(result.Properties["nETBIOSName"][0].ToString()); 
+0

Avez-vous vérifié que 'RootDSE.Properties [" configurationNamingContext "]. Value' renvoie une valeur qui n'est pas nulle, ou respecte la nomenclature LDAP de' LDAP: // CN = Partitions, DC = ktregression , DC = com' ou similaire? –

+0

Avez-vous pris connaissance de l'exemple de code que je vous ai fourni pour votre autre question similaire d'hier? –

+0

@Will, ouais j'ai jeté un coup d'oeil et je l'ai essayé. J'ai répondu à cela avec une autre question. Je pense que j'ai deux problèmes distincts, c'est pourquoi j'ai aussi commencé celui-ci. Le problème où j'ai une instance de deux racines dans une seule forêt. –

Répondre

2

Il semble que le compte d'utilisateur avec lequel Active Directory tente d'authentifier "vous" n'existe pas car votre DirectoryServicesCOMException le signale.

DirectoryServicesCOMException: Échec d'ouverture de session: nom d'utilisateur inconnu ou mot de passe incorrect.

Regardez votre exemple de code, il semble que vous ne l'utilisez l'usurpation d'identité, d'où le protocole de sécurité de l'Active Directory prendre en compte l'utilisateur authentifié. Faites cet utilisateur vous-même, et si vous ne parvenez pas à être défini sur vos deux racines de domaine, l'un d'eux ne vous connaît pas, ce qui crée ce genre d'exception. D'autre part, l'utilisation d'une usurpation d'identité pourrait résoudre le problème ici, puisque vous dites que votre compte Windows Service a le droit d'interroger vos racines sous la même forêt, alors vous devez vous assurer que l'utilisateur authentifié est votre service Windows. En clair, cela signifie que sans usurpation d'identité, vous ne pouvez pas garantir que l'utilisateur authentifié est votre service Windows. Pour s'en assurer, l'usurpation d'identité est un usage obligatoire.

Maintenant, en ce qui concerne les deux racines

  1. ktregression.com;
  2. kregression.root.

Ce sont deux racines différentes et indépendantes. Pour cette raison, je suppose que vous devriez aller avec deux instances de la classe DirectoryEntry en ajustant un pour chaque racine. Après avoir instancié les racines, vous devez rechercher l'utilisateur que vous voulez trouver, qui doit être un autre userName différent de celui qui est usurpé.

Nous devons maintenant indiquer si un utilisateur peut être défini sur les deux racines. Si c'est le cas, vous aurez besoin de savoir quand il est préférable de choisir l'un sur l'autre. Et c'est d'une autre préoccupation.

Remarque
Par souci de simplicité, je considérerai que sont complets/complet que vous avez mentionné le nom des deux racines.

private string _dotComRootPath = "LDAP://ktregression.com"; 
private string _dotRootRootPath = "LDAP://ktregression.root"; 
private string _serviceAccountLogin = "MyWindowsServiceAccountLogin"; 
private string _serviceAccountPwd = "MyWindowsServiceAccountPassword"; 

public string GetUserDomain(string rootPath, string login) { 
    string userDomain = null; 

    using (DirectoryEntry root = new DirectoryEntry(rootPath, _serviceAccountLogin, _serviceAccountPwd)) 
     using (DirectorySearcher searcher = new DirectorySearcher()) { 
      searcher.SearchRoot = root; 
      searcher.SearchScope = SearchScope.Subtree; 
      searcher.PropertiesToLoad.Add("nETBIOSName"); 
      searcher.Filter = string.Format("(&(objectClass=user)(sAMAccountName={0}))", login); 

      SearchResult result = null; 

      try { 
       result = searcher.FindOne(); 

       if (result != null) 
        userDomain = (string)result.GetDirectoryEntry() 
            .Properties("nETBIOSName").Value;          
      } finally { 
       dotComRoot.Dispose(); 
       dotRootRoot.Dispose(); 
       if (result != null) result.Dispose(); 
      } 
     }    

    return userDomain; 
} 

Et l'utiliser:

string userDomain = (GetUserDomain(_dotComRoot, "searchedLogin") 
         ?? GetUserDomain(_dotRootRoot, "searchedLogin")) 
        ?? "Unknown user"; 

Votre exception est levée uniquement sur la deuxième DirectoryEntry initilization ce qui suggère que votre utilisateur par défaut actuel ne dispose pas d'un compte défini sur cette racine.

EDIT # 1

S'il vous plaît voir ma réponse à votre autre nom NetBIOS ci-dessous question concernant:
C# Active Directory: Get domain name of user?
où je fournir une solution nouvelle et probablement plus facile à votre préoccupation. Informez-moi si vous avez d'autres questions. =)

0

Je crois que le DirectoryEntry a des propriétés à spécifier pour un compte AD qui peut effectuer des requêtes LDAP ou mises à jour, vous pouvez Déléguez également ce contrôle de votre domaine parent.

+0

Max, pouvez-vous élaborer là-dessus? Avez-vous un échantillon de code? –

Questions connexes