Ejecutar código con todos los permisos desde un recurso de red

Esta pregunta ha surgido en uno de los cursos de campusMVP que imparto y me ha parecido interesante comentarla aquí.

Resulta que un alumno tenía un ejecutable que, entre otras cosas, necesitaba escribir una serie de registros en un inofensivo archivo de texto. Al ejecutar la aplicación en local todo iba perfectamente, pero al hacerlo cuando el .exe estaba en una unidad de red compartida o en una carpeta remota el programa, lógicamente, le rompía con un error de falta de permisos.

El motivo de que no funcione el código en estas circunstancias es que, al ejecutarlo desde la Red, el ejecutable cae bajo el conjunto de permisos "LocalIntranet" que es mucho más recortado que el conjunto normal que se aplica a los ejecutables .NET y que se llama "FullTrust".

Lo primero que se debería hacer es declarar los permisos que el código necesita para que al menos el runtime pueda saber qué necesita esos permisos antes de "petar", nada más intentar ejecutarla. De este modo si se ejeucta sin los permisos suficientes advierte antes de ello y no se limita a romper cuando la aplicación vaya a escribir a disco. Eso se consigue con este atributo aplicado al ensamblado:

<Assembly:FileIOPermission(SecurityAction.RequestMinimun, Unrestricted:=True)>
De esta forma declaras que tu ensamblado necesita permisos de acceso a disco y el runtime ya lo sabe antes de que se vaya a producir el error.
 
Aparte de eso se puede usar la herramienta de configuración de seguridad para elevar los permisos de la carpeta compartida en la que estén esos ejecutables. Está en Inicio·Panel de control·Herramientas Administrativas·Microsoft .NET Framework Configuration. Se puede cambiar el conjunto de permisos a aplicar a cada elemento que se pueda ejecutar en el sistema desde la interfaz gráfica.
 
Dado que tendremos que hacerlo en cada equipo que lo vaya a ejecutar, si lo pudiésemos automatizar desde línea de comandos mejor. Para ello se puede usar desde la línea de comandos la herramienta equivalente caspol.exe y meterla en un .bat por ejemplo, así:
 
CasPol.exe -m -ag 1.2 -url file://MiUnidadDeRed/MiCarpeta/* FullTrust
De esta forma indicas que se añada un nuevo conjuto de permisos a nivel de máquina (-m), para la intranet local (grupo 1.2) que otorgue permisos totales a la carpeta de red indicada en la ruta. El asterisco final se puedes sustituir para coincidir con cualquier patrón de archivo o por el nombre de un ejecutable concreto para afinar más.
 
Se puede ver el resultado en la herramienta gráfica de la siguiente manera (el grupo se ha creado sin nombre asociado):
 


Pulsa para agrandar

Para ejecutar con éxito esta herramienta necesitas permisos de administrador, claro.
Archivado en:
Comparte este post:

Comentarios

# Victor Moreno said:

Hola José,

Te escribo porque estoy en una situación similar. Mi problema es que tengo una aplicación en la cual se lleva un log de las transacciones. El problema es el siguiente: en una pc donde se corre la aplicacion se crea una carpeta compartida y en ella se crean los logs, es decir, la maquina 1 graba localmente; por otro lado, en una pc distinta, se corre la misma aplicacion, pero en lugar de guardar el log localmente se guarda en la pc1 usando un URL hacia la carpeta compartida, la usuario de la pc2 posee control total sobre la carpeta compartida. La creación y modificación de archivos de texto se realiza sin problemas, sin embargo se presenta el siguiente escenario: cuando la pc1 (local) crea un log, la pc2 no puede agregar texto, ya que se genera una excepcion, cuando el log es creado por la pc remota (pc2) no hay ningun problema. He estado buscando información al respecto y tu post es lo mas cercano que he encontrado, así que me permití escribirte para ver si podias darme un consejo:

De antemano agradezco tu atencion

Saludos

Monday, December 17, 2007 8:53 PM
# Mario said:

Estimado,

Tengo una aplicacion que me envia el error que indicas. Segui los siguientes pasos: support.microsoft.com/.../es

El problema es que no se soluciona el problema y trate de hacer un .bat para que se ejecute pero el problema es que si no corre dentro de la carpeta de framework no reconoce el comando...

Conoces alguna solucion?

Monday, December 17, 2007 9:08 PM
# José M. Alarcón Aguín said:

Hola Victor:

Pienso que el problema que tienes no se relaciona con lo de este post. Más bien me inclino a pensar que es un problema de bloqueos entre procesos ya que seguramente estás abriendo el archivo de modo exclusivo y por lo tanto los otros intentos de escritura se ven bloqueados.

Si intentas escribir desde dos ubicaciones al mismo tiempo en un mismo archivo debes abrir sin ser en modo exclusivo y además debes establecer algún tipo de sistema de sincronización entre los procesos que quieren escribir.

Lo mejor par ano complicarte tal vez sería crear un servicio web o un componente remoto (con Remoting o WCF) que se encargue de la escritura del log, y que los distintos programas que deseen escribir que llamen a ese servicio.

Saludos

JM.

Monday, December 17, 2007 9:25 PM
# José M. Alarcón Aguín said:

Mario:

La solución pasa por hacer lo que pongo en el post: es deicr, otorgarle los permsiso que necesite en esa carpeta tu aplicaicón usando el editor de políticas.

No puedes hacer otra cosa,

Saludos

JM.

Monday, December 17, 2007 9:27 PM
# Victor Moreno said:

OK. Muchas gracias por tu ayuda Jose!!!!

Tuesday, December 18, 2007 12:56 AM
# Mario said:

Estimado,

Al final conseguí esta solucion:

%systemroot%\Microsoft.NET\FrameWork\v1.1.4322\Caspol.exe -s off

%systemroot%\Microsoft.NET\FrameWork\v2.0.50727\Caspol.exe -s off

\\servidor\archivo.exe

Te queria molestar una vez mas...

Intente ejecutar la aplicacion a un usuario de la Red pero le aparece este error: La aplicacion no se ha podido inicializar (0xc0000135)

Te agradeceria si me indicas si es un error de Dll's o que... Ya que necesito ejecutar esta aplicacion a unos 4.000 usuarios.

Tuesday, December 18, 2007 3:05 PM
# José M. Alarcón Aguín said:

Bufff!, pero así lo que estás haciendo es desconectatar la seguridad por completo!!

Eso no deberías hacerlo, no tiene sentido...

Lo que no tiene sentido, por cierto, es ejecutar un programa para 4.000 usuarios en una carpeta de red (si eso es lo que pretendes). Piensa en buscar el  modo de repartir la aplicación en componentes y distribuirla por tu red usando, o usar una política de Directorio Activo para instalarla automáticamente por la red, etc...

Saludos

JM

Tuesday, December 18, 2007 5:26 PM
# Mario said:

Jose,

Lo que sucede es que la aplicacion se usara para 4.000 usuarios pero en un largo proceso. A medida de que se vaya atendiendo un usuario se ejecuta la aplicacion, la verdad es un proceso largo de explicar.

Mi duda es... Por que me envia ese error en algunos equipos?. Tiene solucion dicho problema?.

Gracias por toda la ayuda.

Wednesday, December 19, 2007 1:52 PM
# José M. Alarcón Aguín said:

Pues nada: Si te da ese error es porque hay un permiso (pueden ser muchos, desde acceso a disco hasta el uso de la interfaz gráfica) que el que está ejecutando la aplicaicón no tiene privilegios para ejecutar.

Lo único que puedes hacer es averiguar a qué recursos estás intentando acceder y por lo tanto qué permisos necesitas. Una vez averiguados, con la herramienta de configuración, le otorgas permisos en el ámbito de la máquina, de usuario, o lo que le corresponda y te debería funcionar.

Fíjate en que desconectándolos del todo como has hecho, la cosa funciona, así que los tiros van por ahí.

Siento no poder ser más específico.

Saludos

JM.

Wednesday, December 19, 2007 2:19 PM
# Miguel Alba said:

Ayuda ccon este error por favor, intento ejecuttar esto:

Caspol -machine -addgroup 1 -url http://73.21.10.26/* FullTrust -n CMVT

y me sale el error de "La aplicacion no ha podido inicializar correctamente (0xc000007b)

Friday, February 8, 2008 9:12 PM
# Luis Vasquez said:

Buenos Días, he tenido el mismo problema y he seguido las instrucciones dada pero me sigue saltando el error al intentar ejecutar la aplicación desde la red: el error es el siguiente:

An unhandled exception of type 'System.InvalidOperationException' occurred in Microsoft.VisualBasic.dll

Additional information: An error occurred creating the form. See Exception.InnerException for details.  The error is: Request for the permission of type 'System.Security.Permissions.UIPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' failed.

Si pueden ayudarme estaría agradecido ya que tengo este error desde hace mas de dos semanas y no he dado con la solución !

Monday, September 15, 2008 3:51 PM
# Francisco said:

Hola que tal, tengo un pc que no me corre ninguna aplicacion .net, me dice: "La aplicacion no ha podido inicializar correctamente (0xc000007b)".

Ya no se que hacer, porque he formateado 6 veces y sigo con el mismo problema cuando quiero ejecutar una aplicacion .net.

Tuesday, November 11, 2008 7:05 PM
# Iñigo said:

Hola José M. Me ha parecido muy interesante tu artículo. Ahora bien, tengo un problema, al añadir la linea que comentas en el ensamblado, al ejecutar la aplicacion desde una unidad de red, ahora directamente peta con un error "---" ha detectado un error y debe cerrarse... Alguna sugerencia? Muchas gracias de antemano.

Friday, February 6, 2009 6:17 PM
# Gise said:

Hola:

tengo una aplicacion windowsform corriendo en windows server 2003; las sucursales se conectan de forma remota, pero al intentar imprimir con la miniprinter aparece el error de System. Drawing acceso denegado, y si usa cualquier otra impresora lo hace de forma correcta. ¿que sucede...?

Friday, June 5, 2009 1:55 AM
# Conocuica said:

Hola.

Tengo un problema parecido estoy tratando de ejecutar una aplicacion desde vb.net que he creado tambien en vb.net con el process pero con un usuario de RED y mis errores son los siguientes.

No se controló Win32Exception

El nombre del directorio no es válido

te adjunto mi codigo espero puedas ayudarme

       Dim usuario As String = "usuario"

       Dim contraseña As String = "Password"

       Dim dominio As String = "Domino de red"

       Dim password As New SecureString()

       Dim c As Char

       For Each c In contraseña

           password.AppendChar(c)

       Next c

       Dim proceso As New System.Diagnostics.Process

       Dim archivo As String = "c:\WindowsApplication9.exe"

       proceso.StartInfo.UseShellExecute = False

       proceso.StartInfo.UserName = usuario

       proceso.StartInfo.Password = password

       proceso.StartInfo.Domain = dominio

       proceso.StartInfo.CreateNoWindow = True

       proceso.StartInfo.FileName = archivo

       proceso.StartInfo.WindowStyle = ProcessWindowStyle.Hidden

       proceso.Start()

       proceso.CloseMainWindow()

       proceso.Close()

Thursday, February 25, 2010 1:50 AM
# DarkMedel said:

Me ha sido de gran utilidad tu blogs.  Segundo cuando doy privilegios a un sitio que utiliza una dll me funciona bien, pero al reemplazarla por una nueva versión ya no la ejecuta, sera un problema de permisos???

Friday, July 30, 2010 2:29 AM
# Novato said:

Hola!!

Estoy con una aplicacion en C# .NET 2.0, CF 2.0, y necesito enviar por Red (WIFI) un archivo de texto, a una carpeta en una PC.

despues de leer e investigar, necesito saber d´pnde ó como hago esto:

<Assembly:FileIOPermission(SecurityAction.RequestMinimun, Unrestricted:=True)>

Por favor, agradeceria mucho tu ayuda.

Hasta pronto!

Tuesday, August 17, 2010 2:12 AM