2010-02-16 21 views
7

Me di cuenta que si cambia la configuración de seguridad de un directorio en particular, puede hacer que esa carpeta deje de ser "explorable" en Windows. En particular, al cambiar el permiso de "Lectura" para que los Administradores "Deneguen", esa carpeta quedará inaccesible.Lea los permisos de un directorio en C#

La pregunta que tengo ahora, es ¿cómo lo averiguo en el código? Me siguiente obtiene cerca de mí, pero todavía no está bien:

/// <summary> 
/// Takes in a directory and determines if the current user has read access to it (doesn't work for network drives) 
/// THIS IS VERY HACKY 
/// </summary> 
/// <param name="dInfo">directoryInfo object to the directory to examine</param> 
/// <returns>true if read access is available, false otherwise</returns> 
public static bool IsDirectoryReadable(DirectoryInfo dInfo) 
{ 
    try 
    { 
     System.Security.AccessControl.DirectorySecurity dirSec = dInfo.GetAccessControl(); 
     System.Security.Principal.WindowsIdentity self = System.Security.Principal.WindowsIdentity.GetCurrent(); 
     System.Security.Principal.WindowsPrincipal selfGroup = new System.Security.Principal.WindowsPrincipal(self); 
     // Go through each access rule found for the directory 
     foreach (System.Security.AccessControl.FileSystemAccessRule ar in dirSec.GetAccessRules(true, true, typeof(System.Security.Principal.SecurityIdentifier))) 
     { 
      if (selfGroup.IsInRole((System.Security.Principal.SecurityIdentifier)ar.IdentityReference)) 
      { 
       // See if the Read right is included 
       if ((ar.FileSystemRights & System.Security.AccessControl.FileSystemRights.Read) == System.Security.AccessControl.FileSystemRights.Read) 
       { 
        if (ar.AccessControlType == System.Security.AccessControl.AccessControlType.Allow) 
        { 
         // If all of the above are true, we do have read access to this directory 
         return true; 
        } 
        else 
        { 
         return false; 
        } 
       } 
      } 
     } 
     // If we didn't find anything 
     return false; 
    } 
    catch 
    { 
     // If anything goes wrong, assume false 
     return false; 
    } 
} 

estoy cerca con lo anterior, pero todavía me falta algo enorme. Si hago clic con el botón derecho en una carpeta para establecer los permisos, veo (en mi ejemplo) 3 grupos o nombres de usuario: "Administradores, myUserName y SYSTEM". Si configuro "Leer" en Denegar para "Administradores" o "miNombre de usuario", ya no puedo navegar por el directorio. Si solo configuro "Sistema" en "Denegar", aún puedo buscarlo.

Parece haber algún tipo de jerarquía de permisos implícitos, donde myUserName o Administrator reemplaza al grupo/usuario SYSTEM.

El código de arriba busca el primer Permitir "Leer" que encuentra para mi identidad de usuario y devuelve verdadero. También podría escribir código que busque el primer "Denegar" para Leer y devuelva falso.

Puedo configurar una carpeta para que sea Lectura - "Denegar" para SISTEMA y Leer - "Permitir" para las otras dos cuentas y seguir leyendo la carpeta. Si cambio el código para buscar el de Deny y encuentra primero la identidad del usuario del SISTEMA, mi función devolverá "falso", que es ... falso. Muy bien podría ser Leer - "Permitir" para las otras dos cuentas.

El problema que todavía no puedo resolver es, ¿cómo puedo determinar qué permiso de identidad de usuario tiene prioridad sobre todos los demás?

+2

La cuenta del SISTEMA es solo una cuenta normal, no la trates especialmente. Es utilizado por los servicios. –

Respuesta

3

Se vuelve muy complicado porque las ACL permiten la herencia, pero también tienen un modelo de acceso más restrictivo. En otras palabras, si tiene una DENY en cualquier parte de su cadena de usuarios a un recurso, no importa cuántos otros grupos le den un ALLOW, se le denegará. There is a good article on the subect on MSDN.

2

El grupo de sistemas está relacionado con el proceso de O/S y no está directamente relacionado con su cuenta de usuario. Es lo que el O/S usaría para acceder al sistema de archivos si no hubiera un contexto de usuario. Dado que su aplicación se ejecuta como su "nombre de usuario", los permisos provienen de ella y de los grupos en los que se encuentra. No creo que deba estar revisando el sistema en este caso, a menos que me falta algo.

Actualización: Tenga en cuenta que Directory.Exists() también comprobará que tiene permisos para leer el directorio.

+0

Tengo tanto "Leer" como "Mostrar contenido" en Denegar para mi usuario actual para un directorio. No puedo hacer doble clic en este directorio. Si intento (myDirectoryInfo.Exists), aparece como "verdadero". Hmmm ... No parece estar funcionando ... Tampoco funciona con (Directory.Exists()) – Nick

+0

Interesante, dice * Si no tiene, como mínimo, permiso de solo lectura para el directorio, existe El método devolverá false. * Tal vez signifique permisos de lectura en la carpeta principal ya que puede ver el directorio pero no su contenido. –

0

El problema no es una jerarquía de permisos. El problema es que su código devuelve verdadero o falso según el primer Rol correspondiente. Realmente necesita evaluar todos los permisos.

Recientemente tuve que lidiar con este problema ... Publiqué mi código here.

+0

"El recurso que estás buscando ha sido eliminado, ha cambiado su nombre o no está disponible temporalmente". ¿Podría publicarlo como una respuesta real, como se lo solicitan las pautas de SO? –

Cuestiones relacionadas