c# - usuarios - Agregar miembro al grupo AD desde un dominio confiable
listar usuarios de un grupo active directory powershell (2)
Tengo dos dominios, en una relación de confianza, que trato de administrar desde una aplicación web de C #. Para hacer eso, tengo que suplantar a dos usuarios técnicos diferentes, pero eso funciona bien, así que no enfatizaré esa parte del código.
Para crear ACL adecuadas y fáciles de administrar para el sistema de archivos, debo
- Crea un grupo en domainA (OK!)
- Encuentra un usuario en el dominio B (¡OK!)
- Agregue el usuario al grupo (FALLA al realizar cambios, mensaje de error:
There is no such object on the server. (Exception from HRESULT: 0x80072030)
)
Si agrego un usuario del mismo dominio, el código funciona perfectamente, así que creo que solo me falta una pequeña información parcial aquí. Utilicé este documento como referencia y vi esta pregunta también (y algunos más citando este mensaje de error) pero ninguno de ellos ayudó.
Código (bloque try-catch eliminado para hacerlo más simple)
// 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 línea 6 funciona, si la depuro o fuerzo a escribir las propiedades en HttpResponse, está claramente allí. Entonces las consultas LDAP parecen estar bien.
Además, si comento la línea 6 y elimino el comentario 7, entonces básicamente agrego un usuario del mismo dominio, todo funciona milagrosamente . Con domainB, estoy atascado. ¿Algún buen consejo?
Siguiendo su código, veo que está obteniendo de
como parámetro, que está en el Domain A
Luego está creando DirectoryEntry
object dom
, que se está convirtiendo en impersonated
, pero nunca se está utilizando. Sin embargo, está intentando agregar un objeto del Domain B
para usar directamente LDAP
. Esta línea:
de.Invoke("Add", new object[{"LDAP://domainB.company.com/CN=theUserIWantToAdd,OU=MyOU,DC=domainB,DC=company,DC=com" });
no se está haciendo impersonated
Suponiendo que su impersonation
funciona correctamente, use el objeto dom
que ya está impersonated
con DirectorySearcher
para encontrar al usuario en el Domain B
y luego agregue el objeto de usuario del Domain B
a 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
Este ejemplo le mostrará cómo obtener un SID
de un dominio, un grupo de búsqueda de otro dominio y agregar un usuario al grupo mediante 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();
}
}
}
}
}
Tenga en cuenta que salté toda la impersonation
en el código anterior.
Lo que finalmente funcionó fue usar principios como lo sugirió Burzum. Las muestras de código original que puede ver en el artículo de MSDN vinculado en la pregunta no funcionó aquí. Entonces, el enfoque basado en Principal no es suficiente. Necesita una línea más antes de realizar cambios del nuevo grupo:
group.Properties["groupType"].Value = (-2147483644);
El valor predeterminado era 0x8000000 y tuve que cambiarlo a 0x80000004 para permitir que aceptara FSP de otro dominio.
Entonces ahora el grupo existe, tiene miembros, se agrega a la ACL de la carpeta.