2009-05-26 10 views
5

Qui ho una domanda piuttosto oscura.Un modo affidabile per determinare se le autorizzazioni ntfs sono state ereditate

Cosa mi serve: per determinare se sono state ereditate le autorizzazioni (o, in senso stretto, un ACE specifico di un DACL) di un file/cartella.

Come ho provato a risolvere questo problema: utilizzando winapi binding per python (modulo win32security, per essere precisi). Ecco la versione ridotta, che fa proprio questo, - prende semplicemente un percorso per un file come argomento e stampa gli ACE uno per uno, indicando quali flag sono impostati.

#!/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:]) 

abbastanza semplice - ottenere un descrittore di protezione, ottenere un DACL da esso poi iterare attraverso le voci ACE nel DACL. Il bit davvero importante qui è il flag di accesso INHERITED_ACE. Dovrebbe essere impostato quando l'ACE viene ereditato e non impostato in modo esplicito.

Quando si crea una cartella/file, il relativo ACL viene popolato con voci ACE in base agli ACE dell'oggetto principale (cartella), che vengono impostati per propagarsi ai figli. Tuttavia, se non si apportano modifiche all'elenco di accesso, NON verrà impostato il flag INHERITED_ACE! Ma le autorizzazioni ereditate sono lì e funzionano.

Se si apportano piccole modifiche (ad esempio, aggiungere una voce all'elenco di accesso, applicare le modifiche ed eliminarlo), la bandiera appare magicamente (il comportamento non cambia in alcun modo, tuttavia, ha funzionato prima e funziona in seguito)! Quello che voglio è trovare la fonte di questo comportamento del flag INHERITED_ACE e, forse, trovare un altro affidabile modo per determinare se l'ACE è stato ereditato o meno.

come riprodurre:

  1. Creare un oggetto (file o una cartella)
  2. Verificare le autorizzazioni in Windows Explorer, vedere che sono state propagate dall'oggetto padre (utilizzando, per esempio, scheda di sicurezza del file di finestra di dialogo delle proprietà di Windows Explorer).
  3. Controllare i flag utilizzando, ad esempio, lo script che stavo usando (INHERITED_ACE NON sarà impostato su alcun ACE).
  4. Modificare i permessi di un oggetto (applicare le modifiche), cambiarli di nuovo anche.
  5. Controllare le bandiere (INHERITED_ACE sarà essere lì)
  6. ..shake la testa incredulo (so che ho fatto)

Scusate per un po 'lungo post, spero che questo rende almeno un po' senso.

+0

Ho aggiornato la mia risposta. Questo sembra essere un problema con le librerie Python ... –

risposta

0

Sul mio Win XP Home Edition di questo codice non sembra funzionare affatto :-)

ottengo questo stack trace:

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'

si può solo cercare di "spingere" il DACL Essere riempito? Voglio dire, se sai che funzionerà dopo aver apportato un leggero cambiamento in esso ... fai una leggera modifica a livello di codice, aggiungi uno stub ACE e rimuovilo. Puoi?

AGGIORNAMENTO. Ho fatto un esperimento con un programma C# sulla mia macchina da lavoro (con Win XP Prof) e devo dirvi che il modo .net di ottenere queste informazioni sulla sicurezza funziona davvero. Quindi, quando creo un nuovo file, il mio programma C# rileva che gli ACE sono stati ereditati, mentre il tuo codice Python no.

Ecco l'output di esempio delle mie piste:

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

mio C# classe:

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(); 
    } 
} 

Quindi, sembra essere un bug nella libreria di pitone di sicurezza pywin32. Forse non stanno facendo tutto il sistema necessaria chiama ...

+0

Sì, questo sicuramente non funzionerà nella versione home - le autorizzazioni ntfs sono disabilitate lì, per quanto ne so (quindi stai ottenendo None come risultato di GetSecurityDescriptorDacl). Probabilmente hai ragione nel suggerire che dovrei semplicemente usare uno stub ACE per risolvere i DACL. Tuttavia, considera il fatto che ho bisogno di eseguire questo tipo di codice su un enorme file server aziendale (pensa, milioni di oggetti). Cosa succede se io (o te) sbaglio nella mia ipotesi? E se qualcosa si incasina? Non eseguirò le scritture su questo tipo di dati a meno che non sia assolutamente inevitabile. – shylent

+0

Non riesco a credere che la tua risposta sia stata effettivamente ridimensionata da qualcuno. Comunque, grazie mille per il tuo impegno. Non ho modo di verificare se il tuo suggerimento è corretto (non ho l'ambiente), ma comunque mi sembra abbastanza solido. Lavorerò attorno a questo problema controllando ACE dall'elenco di accesso dell'oggetto padre. Grazie per l'impegno, hai guadagnato questa taglia :) – shylent

+0

Bene, gli ACE possono essere copiati su nodi figli, non ereditati ... Ma se si adatta alle tue esigenze, non vedo alcun problema :-) Comunque, avendo queste prove tu può probabilmente inviare un bug allo sviluppo di python ... –

1

È possibile utilizzare il framework .Net

System.Security.AccessControl 

Questo comprende ACL e DACL e SACL.

+0

L'uso di .Net è fuori questione, sfortunatamente. Ad ogni modo, esaminando le voci msdn su System.Security.AccessControl, ho concluso che, in essenza, non fornisce funzionalità aggiuntive sull'API C (almeno non nell'area in cui sono interessato), - la mia domanda era non su come recuperare i flag di ereditarietà, che è banale, ma piuttosto sull'incoerenza del flag INHERITED_ACE. – shylent

1

Penso che il manifesto originale è un comportamento visto in dettaglio nella

This newsgroup posting

Nota che i flag di controllo impostati sul contenitore può cambiare semplicemente deselezionando e segnando nuovamente la casella di ereditarietà nella GUI.

Inoltre, aggiungere semplicemente un ACE al DACL utilizzando gli strumenti di Microsoft cambierà anche i flag di controllo.

Si noti inoltre che la GUI, cacls e icacl NON può essere invocata quando si tratta di ereditarietà a causa di molti bug sottili come discusso nella pubblicazione di newsgroup.

Sembra che il "vecchio" modo di controllare l'ereditarietà fosse utilizzare i flag di controllo sul contenitore in combinazione con i flag ACE relativi all'ereditarietà.

Il "nuovo" modo non utilizza i flag di controllo sul contenitore e utilizza invece voci ACE duplicate; uno per controllare l'accesso all'oggetto e un secondo per controllare ciò che è ereditato dagli oggetti figli.

MA, sembra che gli strumenti Microsoft esistenti (ad esempio Vista) non possano ancora funzionare nel modo "nuovo", quindi quando si effettua una semplice modifica utilizzando gli strumenti, si ricorre al vecchio modo di utilizzare i flag di controllo sul contenitore.

Se si crea una nuova partizione su Vista, quindi creare una nuova cartella, poi guardare le bandiere e gli assi, sarà simile a questa

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 i ControlFlags e le voci ACE duplicati.

Problemi correlati