2009-05-26 641 views
5

Tengo una pregunta algo oscura aquí.Una forma confiable de determinar si los permisos ntfs se heredaron

Lo que necesito: determinar si los permisos (o, estrictamente hablando, un ACE específico de una DACL) de un archivo/carpeta se heredaron.

Cómo traté de resolver esto: usando enlaces de winapi para python (módulo win32security, para ser precisos). Aquí está la versión simplificada, que hace precisamente eso, simplemente toma una ruta a un archivo como argumento e imprime las ACEs una a una, indicando qué banderas están establecidas.

#!/usr/bin/env python 
from win32security import * 
import sys 

def decode_flags(flags): 
    _flags = { 
     SE_DACL_PROTECTED:"SE_DACL_PROTECTED", 
     SE_DACL_AUTO_INHERITED:"SE_DACL_AUTO_INHERITED", 
     OBJECT_INHERIT_ACE:"OBJECT_INHERIT_ACE", 
     CONTAINER_INHERIT_ACE:"CONTAINER_INHERIT_ACE", 
     INHERIT_ONLY_ACE:"INHERIT_ONLY_ACE", 
     NO_INHERITANCE:"NO_INHERITANCE", 
     NO_PROPAGATE_INHERIT_ACE:"NO_PROPAGATE_INHERIT_ACE", 
     INHERITED_ACE:"INHERITED_ACE" 
    } 
    for key in _flags.keys(): 
     if (flags & key): 
      print '\t','\t',_flags[key],"is set!" 


def main(argv): 
    target = argv[0] 
    print target 

    security_descriptor = GetFileSecurity(target,DACL_SECURITY_INFORMATION) 

    dacl = security_descriptor.GetSecurityDescriptorDacl() 

    for ace_index in range(dacl.GetAceCount()): 
     (ace_type,ace_flags),access_mask,sid = dacl.GetAce(ace_index) 
     name,domain,account_type = LookupAccountSid(None,sid) 
     print '\t',domain+'\\'+name,hex(ace_flags) 
     decode_flags(ace_flags) 


if __name__ == '__main__': 
    main(sys.argv[1:]) 

Bastante simple - obtener un descriptor de seguridad, obtener una DACL de ella a continuación, iterar a través de las ACE en la DACL. El bit realmente importante aquí es el indicador de acceso INHERITED_ACE. Se debe configurar cuando el ACE se hereda y no se establece explícitamente.

Cuando crea una carpeta/archivo, su ACL se rellena con ACEs de acuerdo con las ACE del objeto principal (carpeta), que están configuradas para propagarse a los elementos secundarios. Sin embargo, a menos que realice algún cambio en la lista de acceso, NO se establecerá el indicador INHERITED_ACE. Pero los permisos heredados están ahí y funcionan.

Si hace un cambio leve (por ejemplo, agrega una entrada a la lista de acceso, aplica cambios y la elimina), la bandera aparece mágicamente (el comportamiento no cambia de ninguna manera, sin embargo, funcionó antes y funciona después)! Lo que quiero es encontrar el origen de este comportamiento de la bandera INHERITED_ACE y, tal vez encontrar otra forma confiable para determinar si el ACE fue heredado o no.

cómo reproducir:

  1. crear un objeto (archivo o carpeta)
  2. Compruebe los permisos en el Explorador de Windows, ver que se han propagado desde el objeto padre (usando, por ejemplo, ficha de seguridad del archivo diálogo de propiedades del explorador de Windows).
  3. Revise las banderas usando, por ejemplo, la secuencia de comandos que estaba usando (INHERITED_ACE NO se establecerá en ninguna ACE).
  4. Cambie los permisos de un objeto (aplique los cambios), cámbielos nuevamente.
  5. comprueba los indicadores (INHERITED_ACE se estar allí)
  6. ..shake su cabeza con incredulidad (Sé que lo hice)

Lo siento por un tanto extenso post, espero que esto hace al menos un poco sentido.

+0

He actualizado mi respuesta. Esto parece ser un problema con las bibliotecas de Python ... –

Respuesta

0

En mi Win XP Home Edition este código no parece funcionar en absoluto :-)

consigo este seguimiento de la pila:

Traceback (most recent call last):
File "C:\1.py", line 37, in main(sys.argv[1:])
File "C:\1.py", line 29, in main for ace_index in range(dacl.GetAceCount()):

AttributeError: 'NoneType' object has no attribute 'GetAceCount'

¿Puede usted acaba de tratar de "empujar" la DACL ser llenado? Quiero decir, si sabes que va a funcionar después de hacer un pequeño cambio en él ... haz un ligero cambio programáticamente, agrega un trozo de ACE y quítalo. ¿Puedes?

ACTUALIZACIÓN. Hice un experimento con un programa C# en mi máquina de trabajo (con Win XP Prof) y debo decirle que la forma .net de obtener esta información de seguridad realmente funciona. Entonces, cuando creo un nuevo archivo, mi programa C# detecta que las ACE fueron heredadas, mientras que su código python no.

Aquí está el ejemplo del resultado de mis carreras:

C:>csharp_tricks.exe 2.txt

FullControl --> IsInherited: True

FullControl --> IsInherited: True

ReadAndExecute, Synchronize --> IsInherited: True


C:>1.py 2.txt

2.txt

BUILTIN\Administrators 0x0

NT AUTHORITY\SYSTEM 0x0

BUILTIN\Users 0x0

Mi clase de C#:

public class InheritedAce 
{ 
    public static string GetDACLReport(string path) 
    { 
     StringBuilder result = new StringBuilder(); 
     FileSecurity fs = new FileSecurity(path, AccessControlSections.Access); 
     foreach (var rule in fs.GetAccessRules(true, true, typeof(SecurityIdentifier)).OfType<FileSystemAccessRule>()) 
     { 
      result.AppendFormat("{0} --> IsInherited: {1}", rule.FileSystemRights, rule.IsInherited); 
      result.AppendLine(); 
     } 

     return result.ToString(); 
    } 
} 

Por lo tanto, parece que hay un error en la librería de seguridad pywin32 pitón. Tal vez ellos no están haciendo todo el sistema es necesario llama ...

+0

Sí, esto definitivamente no funcionará en la edición hogareña. Los permisos ntfs están deshabilitados allí, hasta donde yo sé (por lo que está obteniendo None como resultado de GetSecurityDescriptorDacl). Tal vez, es correcto en su sugerencia, que debería usar un trozo de ACE para arreglar las DACL. Sin embargo, considere el hecho de que necesito ejecutar este tipo de código en un gran servidor de archivos corporativo (creo, millones de objetos). ¿Qué pasa si yo (o yo) estoy equivocado en mi suposición? ¿Qué pasa si algo se arruina? No voy a realizar grabaciones en este tipo de datos a menos que sea absolutamente inevitable. – shylent

+0

No puedo creer que tu respuesta sea rechazada por alguien. De todos modos, muchas gracias por tu esfuerzo. No tengo forma de comprobar si tu sugerencia es correcta (no tengo el entorno), pero sin embargo, me parece bastante sólida. Resolveré este problema marcando ACE contra la lista de acceso a objetos principal. Gracias por el esfuerzo, te has ganado esta recompensa :) – shylent

+0

Bueno, las ACE pueden copiarse a los nodos de los niños, no hereditarias ... Pero si se adapta a tus necesidades, no veo ningún problema :-) Aún así, teniendo estas pruebas te Probablemente pueda enviar un error al desarrollo de Python ... –

1

Puede utilizar el marco .Net

System.Security.AccessControl 

Esto cubre ACL y DACL y SACL.

+0

El uso de .Net está fuera de lugar, desafortunadamente. De cualquier manera, al examinar las entradas de msdn en System.Security.AccessControl, concluí que, en esencia, no proporciona ninguna funcionalidad adicional sobre la API C (al menos no en el área que me interesa), - mi pregunta era no sobre cómo recuperar banderas de herencia, eso es trivial, sino sobre la incoherencia de la bandera INHERITED_ACE. – shylent

1

creo que el cartel original se detalla en el comportamiento de ver

This newsgroup posting

Tenga en cuenta que los indicadores de control establecidos en el envase pueden cambiar simplemente desmarcar y volver a marcar el casillero de herencia en la GUI.

Además, tenga en cuenta que la simple adición de un ACE a la DACL utilizando las herramientas de Microsoft también cambiará los indicadores de control.

Tenga en cuenta además que la GUI, los catálogos y los icacls NO se pueden confiar cuando se trata de herencia debido a muchos errores sutiles, como se discutió en la publicación del grupo de noticias.

Parece que la "vieja" forma de controlar la herencia era usar las banderas de control en el contenedor en combinación con indicadores de herencia de ACE.

La "nueva" forma no usa los indicadores de control en el contenedor y en su lugar utiliza ACE duplicadas; uno para controlar el acceso en el objeto y otro para controlar lo que heredan los objetos secundarios.

PERO, parece que las herramientas existentes de Microsoft (por ejemplo, Vista) no pueden funcionar de la "nueva" manera, así que cuando haces un cambio simple usando las herramientas, recurre a la vieja forma de usar banderas de control en el envase.

Si crea una nueva partición en Vista, a continuación, crear una nueva carpeta, y luego mirar las banderas y las ACE, que se verá algo como esto

ControlFlags : 0x8004 
Owner : BUILTIN\Administrators 
Group : WS1\None 
S-1-5-32-544 : BUILTIN\Administrators : 0x0 : 0x0 : 0x1F01FF 
S-1-5-32-544 : BUILTIN\Administrators : 0x0 : 0xB : 0x10000000 
S-1-5-18 : NT AUTHORITY\SYSTEM : 0x0 : 0x0 : 0x1F01FF 
S-1-5-18 : NT AUTHORITY\SYSTEM : 0x0 : 0xB : 0x10000000 
S-1-5-11 : NT AUTHORITY\Authenticated Users : 0x0 : 0x0 : 0x1301BF 
S-1-5-11 : NT AUTHORITY\Authenticated Users : 0x0 : 0xB : 0xE0010000 
S-1-5-32-545 : BUILTIN\Users : 0x0 : 0x0 : 0x1200A9 
S-1-5-32-545 : BUILTIN\Users : 0x0 : 0xB : 0xA0000000 

Nota los ControlFlags y las ACE duplicadas.

Cuestiones relacionadas