Ajouter un membre au groupe AD à partir d’un domaine approuvé

J’ai deux domaines, dans une relation de confiance, que j’essaie de gérer à partir d’une application Web C #. Pour ce faire, je dois usurper l’identité de deux utilisateurs techniques différents, mais cela fonctionne bien, donc je ne soulignerai pas cette partie du code.

Pour créer des ACL corrects et faciles à gérer pour le système de fichiers, je dois

  • Créer un groupe dans le domaine A (OK!)
  • Trouver un utilisateur dans domainB (OK!)
  • Ajoutez l’utilisateur au groupe (FAILS lors de la validation des modifications, message d’erreur: There is no such object on the server. (Exception from HRESULT: 0x80072030) )

Si j’ajoute un utilisateur du même domaine, le code fonctionne parfaitement. Je pense donc qu’il ne manque qu’une petite information partielle ici. J’ai utilisé ce document comme référence et j’ai vu cette question aussi (et quelques autres citant ce message d’erreur), mais aucun d’entre eux n’a aidé.

Code (bloc try-catch enlevé pour le simplifier)

 // de is a DirectoryEntry object of the AD group, received by the method as a parameter // first impersonation to search in domainB // works all right if (impersonator.impersonateUser("techUser1", "domainB", "pass")) { DirectoryEntry dom = new DirectoryEntry("LDAP://domainB.company.com/OU=MyOU,DC=domainB,DC=company,DC=com", "techUser1", "pass"); de.Invoke("Add", new object[] { "LDAP://domainB.company.com/CN=theUserIWantToAdd,OU=MyOU,DC=domainB,DC=company,DC=com" }); // de.Invoke("Add", new object[] { "LDAP://domainA.company.com/CN=anotherUserFromDomainA,OU=AnotherOU,DC=domainB,DC=company,DC=com" }); impersonator.undoImpersonation(); } // second impersonation because the group (de) is in domainA // and techUser2 has account operator privileges there if (impersonator.impersonateUser("techUser2", "domainA", "pass")) { de.CommitChanges(); impersonator.undoImpersonation(); return true; } else { // second impersonation was unsuccessful, so return an empty object return false; } 

La ligne 6 fonctionne, si je la corrige ou force les propriétés à être écrites dans HttpResponse, elle est clairement là. Donc, les requêtes LDAP semblent être OK.

De plus, si je commente la ligne 6 et le commentaire 7, je rajoute donc un utilisateur du même domaine, tout fonctionne miraculeusement . Avec domainB, je suis bloqué. Un bon conseil?

Suite à votre code, je vois que vous obtenez de tant que paramètre, qui est dans le Domain A Ensuite, vous créez l’object dom DirectoryEntry , qui se fait impersonated , mais ne s’habitue jamais. Cependant, vous essayez d’append un object du Domain B directement à l’aide de LDAP . Cette ligne:

 de.Invoke("Add", new object[{"LDAP://domainB.company.com/CN=theUserIWantToAdd,OU=MyOU,DC=domainB,DC=company,DC=com" }); 

ne pas se faire impersonated .

En supposant que votre impersonation fonctionne correctement, utilisez l’object dom qui est déjà impersonated avec DirectorySearcher pour rechercher l’utilisateur dans le Domain B , puis ajoutez l’object utilisateur de Domain B à de .

 ... using (DirectoryEntry dom = new DirectoryEntry("LDAP://domainB.company.com/OU=MyOU,DC=domainB,DC=company,DC=com", "techUser1", "pass")) { using (DirectorySearcher searcher = new DirectorySearcher(dom)) { searcher.Filter = "(&(objectClass=user)(CN=theUserIWantToAdd))"; SearchResult result = searcher.FindOne(); de.Invoke("Add", new object[] { result.Path }); } } ... 

UDPATE

Cet exemple vous montrera comment obtenir l’utilisateur SID d’un domaine, rechercher un groupe dans un autre domaine et append un utilisateur à un groupe à l’aide de SID .

 //GET THE USER FROM DOMAIN B using (UserPrincipal userPrincipal = UserPrincipal.FindByIdentity(domainContext, UPN)) { if (userPrincipal != null) { //FIND THE GROUP IN DOMAIN A using (GroupPrincipal groupPrincipal = GroupPrincipal.FindByIdentity(domainContext, groupName)) { if (groupPrincipal != null) { //CHECK TO MAKE SURE USER IS NOT IN THAT GROUP if (!userPrincipal.IsMemberOf(groupPrincipal)) { ssortingng userSid = ssortingng.Format("", userPrincipal.SID.ToSsortingng()); DirectoryEntry groupDirectoryEntry = (DirectoryEntry)groupPrincipal.GetUnderlyingObject(); groupDirectoryEntry.Properties["member"].Add(userSid); groupDirectoryEntry.CommitChanges(); } } } } } 

Veuillez noter que j’ai ignoré toute l’ impersonation dans le code ci-dessus.

Ce qui a finalement fonctionné a été d’utiliser les principes comme le suggérait Burzum. Les exemples de code d’origine que vous pouvez voir dans l’article MSDN lié à la question ne fonctionnaient pas ici. L’approche fondée sur le principe est donc essentielle, mais pas suffisante. Vous avez besoin d’une ligne supplémentaire avant de valider les modifications du nouveau groupe:

 group.Properties["groupType"].Value = (-2147483644); 

La valeur par défaut était 0x8000000 et j’ai dû le modifier en 0x80000004 pour lui permettre d’accepter les FSP d’un autre domaine.

Alors maintenant, le groupe existe, il a des membres, il est ajouté à la liste de contrôle d’access du dossier.