Pytanie Dodaj członka do grupy AD z zaufanej domeny


Mam dwie domeny, w zaufanym związku, które próbuję zarządzać z aplikacji sieci web C #. Aby to zrobić, muszę podszywać się pod dwóch różnych użytkowników technicznych, ale to działa dobrze, więc nie będę podkreślać tej części kodu.

Aby zbudować właściwe i łatwe w zarządzaniu listy ACL dla systemu plików, muszę

  • Utwórz grupę w domenie A (OK!)
  • Znajdź użytkownika w domenie B (OK!)
  • Dodaj użytkownika do grupy (FAILS podczas zatwierdzania zmian, komunikat o błędzie: There is no such object on the server. (Exception from HRESULT: 0x80072030))

Jeśli dodaję użytkownika z tej samej domeny, kod działa idealnie, więc uważam, że brakuje tu tylko niewielkich częściowych informacji. użyłem ten dokument jako odniesienie i zobaczyłem to pytanie także (i kilka innych cytujących ten komunikat o błędzie), ale żadne z nich nie pomogło.

Kod (blokowanie try-catch usunięte, aby było prostsze)

// 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;
}

Wiersz 6 działa, jeśli debuguję go lub wymuszam zapisywanie właściwości w HttpResponse, wyraźnie tam jest. Tak więc zapytania LDAP wydają się być w porządku.

Ponadto, jeśli skomentuję linię 6 i usuń komentarz 7, więc w zasadzie dodaję użytkownika z tej samej domeny, do całość działa cudownie. W domenie B utknąłem. Dobra rada?


10
2017-08-13 09:15


pochodzenie


OK, nadal nie mam kodu, ale znalazłem jedną wskazówkę: z różnych domen członkowie grupy mogą być dodawani jako ForeignSecurityPincipals, więc nie w normalny sposób. - mshthn
Czy masz problem tylko przy próbie dodania użytkownika z jednej domeny do innej grupy domeny lub wykonania innych operacji? Czy w celu testowania możesz spróbować zaktualizować nazwę użytkownika podszywając się pod niego? - smr5
Nie mam uprawnień do obsługi kont w domenie B, więc nie trzeba próbować. W domenie A wszystko działa, mogę tworzyć grupy, użytkownicy, resetować hasła, odblokowywać konta itp. - mshthn


Odpowiedzi:


Podążając za kodem, widzę, że dostajesz de jako parametr, który jest w Domain A. Potem tworzysz DirectoryEntry obiekt dom, który dostaje impersonated, ale nigdy się nie przyzwyczaja. Jednak próbujesz dodać obiekt z Domain B do de bezpośrednio za pomocą LDAP. Ta linia:

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

nie dostaje impersonated.

Zakładając twoje impersonation działa poprawnie, posługiwać się dom obiekt, który już jest impersonated z DirectorySearcher znaleźć użytkownika Domain B a następnie dodaj obiekt użytkownika z Domain B do 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

Ten przykład pokazuje, jak zdobyć użytkownika SID z jednej domeny, grupy wyszukiwania z innej domeny i dodaj użytkownika do grupy za pomocą 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))
             {
                string userSid = string.Format("<SID={0}>", userPrincipal.SID.ToString());
                DirectoryEntry groupDirectoryEntry = (DirectoryEntry)groupPrincipal.GetUnderlyingObject();
                groupDirectoryEntry.Properties["member"].Add(userSid);
                groupDirectoryEntry.CommitChanges();
              }
           }
        }
     }
 }

Pamiętaj, że pominąłem wszystkie impersonation w powyższym kodzie.


5
2017-08-26 08:22



Działa przed ostatnią linią. Tak więc znajduje użytkownika, widzę jego pełną ścieżkę lub dowolną inną właściwość, ale nie można go dodać. Komunikat o błędzie pod adresem de.Invoke: System.DirectoryServices.DirectoryServicesCOMException: Na serwerze nie ma takiego obiektu. (Wyjątek od HRESULT: 0x80072030). Ten komunikat o błędzie pojawił się już przy moim oryginalnym podejściu, uważam, że problem polega na tym, że próbuję zapisać obiekt grupowy w domenie A z członkiem z domeny B. To dlatego obiekt związany z obcym bezpieczeństwem musi być w jakiś sposób zaangażowany. - mshthn
W każdym razie twój komentarz i odpowiedź pomogły mi przejść do wersji 4.5 z 4.0 i dodać System.DirectoryServices.AccountManagement do mojego projektu, dzięki za wskazanie tych! - mshthn
Kiedy przyjrzę się innym grupom w domenie A (utworzonym ręcznie) za pomocą narzędzia SysInternals, widzę, że członkowie z domeny B są dodawani jak "CN = <SID tutaj>, CN = ForeignSecurityPrincipals, DC = domena A, DC = firma, DC = com ". Zobacz różnicę. Tak więc ci użytkownicy mają obiekt również w domenie A, mogę nawet znaleźć je w części CN = ForeignSecurityPrincipals w AD. Najgorsze jest to, że nie zawierają one żadnych czytelnych dla człowieka właściwości, więc nie mogę znaleźć tutaj użytkownika według nazwy lub nazwy samaccount. Nie znaleziono właściwości identyfikującej obiekt w domenieB ... - mshthn
Dobry. Czy możesz opublikować zaktualizowany kod za pomocą AccountManagement przestrzeń nazw? Czy masz dostęp do ADSI narzędzie? - smr5
Czy możesz mi opowiedzieć o grupie? Domain A. Jakiego rodzaju jest to grupa? User, Global, Local? Jakie masz zaufanie między dwiema domenami? Niedługo zaktualizuję swoją odpowiedź ... - smr5


To, co w końcu zadziałało, to wykorzystanie zleceniodawców, jak sugerował Burzum. Oryginalne próbki kodu, które można znaleźć w artykule MSDN połączonym z pytaniem, nie działały tutaj. Tak więc podejście oparte na Zleceniodawcy nie jest wystarczające. Przed wprowadzeniem zmian w nowej grupie potrzebujesz jeszcze jednej linii:

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

Wartością domyślną było 0x8000000 i musiałem zmień go na 0x80000004 aby umożliwić akceptację FSP z innej domeny.

Teraz grupa istnieje, ma członków, jest dodawana do listy ACL folderu.


0
2017-09-02 10:46