Im letzten Artikel zu diesem Thema (Was ist die SID?) haben wir uns mit der SID beschäftigt und herausgefunden, dass sie einen Benutzer oder eine Gruppe auf einen Rechner eindeutig identifiziert und das jedes Sicherheitsobjekt eine SID besitzt. Dies wäre aber nutzlos, wenn damit nicht eine Liste mit Berechtigungen für ein Objekt verknüpft wäre. Und genau das ist die DACL (discretionary access control list) oder auf Deutsch: frei verfügbare Zugriffskontrolliste.
Die DACL enthält eine Liste der Autoritäten, denen Zugriff zu dem Objekt gewährt oder verweigert wird. Diese Liste enthält keinen oder mehrere ACEs (Access control entry), welche jeweils einen Satz Zugriffsrechte und SIDs enthalten, die eine Autorität identifizieren, der der Zugriff gestattet oder verweigert wird auf das Objekt. Besitzt das Objekt keine DACL bewilligt das System vollen Zugriff für jeden auf das Objekt. Besitzt es eine DACL, aber diese enthält keine ACEs, wird jedem der Zugriff auf das Objekt verweigert.
Wird nun auf das Objekt zugegriffen, geht das System die ACE Einträge in der Liste durch und überprüft, ob es einen Eintrag findet, welcher den verlangten Zugriffsrechten entspricht. Dabei steht eine Verweigerung immer über einer Erlaubnis. Hat zum Beispiel Gruppe A Zugriff auf ein Objekt und gehört Alice dieser Gruppe an, aber es wurde ihr explizit der Zugriff nicht gestattet, dann hat sie auch kein Zugriff auf das Objekt, obwohl sie der Gruppe angehört, die eigentlich Zugriff auf das Objekt hat. Das System überprüft dabei jeden ACE bis einer der folgenden Punkte zutrifft:
Da die Überprüfung abgebrochen wird, so bald ein Punkt aus der obigen Liste zutrifft, ist die Reihenfolge der ACEs natürlich wichtig. Lägen im obigen Beispiel Die ACEs in einer anderen Reihenfolge vor, so könnte Alice durchaus Zugriff auf das Objekt bekommen.
Liste der Zugriffsrechte: File Security and Access Rights, Standard Access Rights [1]
Dies kann man auch sehr gut sehen, wenn man zum Beispiel das Delphi Demoprogramm ausführt. Das Demo liest die DACL von sich selber aus und zeigt sie an. Das könnte dann zum Beispiel so aussehen:
D:\Homepage\luckie-online\files\DumpDacl_Delphi\dumpACL.exe
Entry #0
Type : grant
Mask :
SYNCHRONIZE
READ_CONTROL
file: FILE_READ_DATA, dir: FILE_LIST_DIRECTORY
file: FILE_WRITE_DATA, dir: FILE_ADD_FILE
file: FILE_APPEND_DATA, dir: FILE_ADD_SUBDIRECTORY
FILE_READ_EA
FILE_WRITE_EA
file: FILE_EXECUTE, dir: FILE_TRAVERSE
FILE_READ_ATTRIBUTES
FILE_WRITE_ATTRIBUTES
FILE_GENERIC_READ
FILE_GENERIC_WRITE
FILE_GENERIC_EXECUTE
Flags: INHERITED_ACE
Name : \Jeder
SID : S-1-2298417664-4232053
Entry #1
Type : grant
Mask :
SYNCHRONIZE
WRITE_OWNER
WRITE_DAC
READ_CONTROL
STANDARD_RIGHTS_REQUIRED
STANDARD_RIGHTS_ALL
DELETE
file: FILE_READ_DATA, dir: FILE_LIST_DIRECTORY
file: FILE_WRITE_DATA, dir: FILE_ADD_FILE
file: FILE_APPEND_DATA, dir: FILE_ADD_SUBDIRECTORY
FILE_READ_EA
FILE_WRITE_EA
file: FILE_EXECUTE, dir: FILE_TRAVERSE
FILE_DELETE_CHILD
FILE_READ_ATTRIBUTES
FILE_WRITE_ATTRIBUTES
FILE_ALL_ACCESS
FILE_GENERIC_READ
FILE_GENERIC_WRITE
FILE_GENERIC_EXECUTE
Flags: INHERITED_ACE
Name : VORDEFINIERT\Administratoren
SID : S-1-2298417664-4232053-1245072
Entry #2
Type : grant
Mask :
SYNCHRONIZE
WRITE_OWNER
WRITE_DAC
READ_CONTROL
STANDARD_RIGHTS_REQUIRED
STANDARD_RIGHTS_ALL
DELETE
file: FILE_READ_DATA, dir: FILE_LIST_DIRECTORY
file: FILE_WRITE_DATA, dir: FILE_ADD_FILE
file: FILE_APPEND_DATA, dir: FILE_ADD_SUBDIRECTORY
FILE_READ_EA
FILE_WRITE_EA
file: FILE_EXECUTE, dir: FILE_TRAVERSE
FILE_DELETE_CHILD
FILE_READ_ATTRIBUTES
FILE_WRITE_ATTRIBUTES
FILE_ALL_ACCESS
FILE_GENERIC_READ
FILE_GENERIC_WRITE
FILE_GENERIC_EXECUTE
Flags: INHERITED_ACE
Name : HAL9000\Michael
SID : S-1-2298417664-4232053-1245072-4232178-1245064-3604535
Die Bedeutung der Konstanten läßt sich an Hand der oben genannten Links erschließen. Fügt man jetzt einen Benutzer hinzu und verweigert ihm den Vollzugriff, sieht die List dann wie folgt aus:
D:\Homepage\luckie-online\files\DumpDacl_Delphi\dumpACL.exe
Entry #0
Type : deny
Mask :
WRITE_OWNER
WRITE_DAC
READ_CONTROL
STANDARD_RIGHTS_REQUIRED
DELETE
file: FILE_READ_DATA, dir: FILE_LIST_DIRECTORY
file: FILE_WRITE_DATA, dir: FILE_ADD_FILE
file: FILE_APPEND_DATA, dir: FILE_ADD_SUBDIRECTORY
FILE_READ_EA
FILE_WRITE_EA
file: FILE_EXECUTE, dir: FILE_TRAVERSE
FILE_DELETE_CHILD
FILE_READ_ATTRIBUTES
FILE_WRITE_ATTRIBUTES
Flags:
Name : HAL9000\Gast
SID : S-1-2298417664-4232053-1245072-4232178-1245064-3604535
Entry #1
Type : grant
Mask :
SYNCHRONIZE
READ_CONTROL
file: FILE_READ_DATA, dir: FILE_LIST_DIRECTORY
file: FILE_WRITE_DATA, dir: FILE_ADD_FILE
file: FILE_APPEND_DATA, dir: FILE_ADD_SUBDIRECTORY
FILE_READ_EA
FILE_WRITE_EA
file: FILE_EXECUTE, dir: FILE_TRAVERSE
FILE_READ_ATTRIBUTES
FILE_WRITE_ATTRIBUTES
FILE_GENERIC_READ
FILE_GENERIC_WRITE
FILE_GENERIC_EXECUTE
Flags: INHERITED_ACE
Name : \Jeder
SID : S-1-2298417664-4232053
Entry #2
Type : grant
Mask :
SYNCHRONIZE
WRITE_OWNER
WRITE_DAC
READ_CONTROL
STANDARD_RIGHTS_REQUIRED
STANDARD_RIGHTS_ALL
DELETE
file: FILE_READ_DATA, dir: FILE_LIST_DIRECTORY
file: FILE_WRITE_DATA, dir: FILE_ADD_FILE
file: FILE_APPEND_DATA, dir: FILE_ADD_SUBDIRECTORY
FILE_READ_EA
FILE_WRITE_EA
file: FILE_EXECUTE, dir: FILE_TRAVERSE
FILE_DELETE_CHILD
FILE_READ_ATTRIBUTES
FILE_WRITE_ATTRIBUTES
FILE_ALL_ACCESS
FILE_GENERIC_READ
FILE_GENERIC_WRITE
FILE_GENERIC_EXECUTE
Flags: INHERITED_ACE
Name : VORDEFINIERT\Administratoren
SID : S-1-2298417664-4232053-1245072
Entry #3
Type : grant
Mask :
SYNCHRONIZE
WRITE_OWNER
WRITE_DAC
READ_CONTROL
STANDARD_RIGHTS_REQUIRED
STANDARD_RIGHTS_ALL
DELETE
file: FILE_READ_DATA, dir: FILE_LIST_DIRECTORY
file: FILE_WRITE_DATA, dir: FILE_ADD_FILE
file: FILE_APPEND_DATA, dir: FILE_ADD_SUBDIRECTORY
FILE_READ_EA
FILE_WRITE_EA
file: FILE_EXECUTE, dir: FILE_TRAVERSE
FILE_DELETE_CHILD
FILE_READ_ATTRIBUTES
FILE_WRITE_ATTRIBUTES
FILE_ALL_ACCESS
FILE_GENERIC_READ
FILE_GENERIC_WRITE
FILE_GENERIC_EXECUTE
Flags: INHERITED_ACE
Name : HAL9000\Michael
SID : S-1-2298417664-4232053-1245072-4232178-1245064-3604535
Wie man sieht, wurde der Benutzer, hier der Gast, dem man den Vollzugriff verweigert, am Anfang der Liste eingefügt. Differenziert man den Zugriff noch etwas,
könnte die Liste dann so aussehen:
D:\Homepage\luckie-online\files\DumpDacl_Delphi\dumpACL.exe
Entry #0
Type : deny
Mask :
file: FILE_WRITE_DATA, dir: FILE_ADD_FILE
file: FILE_APPEND_DATA, dir: FILE_ADD_SUBDIRECTORY
FILE_WRITE_EA
FILE_WRITE_ATTRIBUTES
Flags:
Name : HAL9000\Gast
SID : S-1-2298417664-4232053-1245072-4232178-1245064-3604535
Entry #1
Type : grant
Mask :
SYNCHRONIZE
READ_CONTROL
file: FILE_READ_DATA, dir: FILE_LIST_DIRECTORY
FILE_READ_EA
file: FILE_EXECUTE, dir: FILE_TRAVERSE
FILE_READ_ATTRIBUTES
FILE_GENERIC_READ
FILE_GENERIC_EXECUTE
Flags:
Name : HAL9000\Gast
SID : S-1-2298417664-4232053-1245072-4232178-1245064-3604535
Entry #2
Type : grant
Mask :
SYNCHRONIZE
READ_CONTROL
file: FILE_READ_DATA, dir: FILE_LIST_DIRECTORY
file: FILE_WRITE_DATA, dir: FILE_ADD_FILE
file: FILE_APPEND_DATA, dir: FILE_ADD_SUBDIRECTORY
FILE_READ_EA
FILE_WRITE_EA
file: FILE_EXECUTE, dir: FILE_TRAVERSE
FILE_READ_ATTRIBUTES
FILE_WRITE_ATTRIBUTES
FILE_GENERIC_READ
FILE_GENERIC_WRITE
FILE_GENERIC_EXECUTE
Flags: INHERITED_ACE
Name : \Jeder
SID : S-1-2298417664-4232053
Entry #3
Type : grant
Mask :
SYNCHRONIZE
WRITE_OWNER
WRITE_DAC
READ_CONTROL
STANDARD_RIGHTS_REQUIRED
STANDARD_RIGHTS_ALL
DELETE
file: FILE_READ_DATA, dir: FILE_LIST_DIRECTORY
file: FILE_WRITE_DATA, dir: FILE_ADD_FILE
file: FILE_APPEND_DATA, dir: FILE_ADD_SUBDIRECTORY
FILE_READ_EA
FILE_WRITE_EA
file: FILE_EXECUTE, dir: FILE_TRAVERSE
FILE_DELETE_CHILD
FILE_READ_ATTRIBUTES
FILE_WRITE_ATTRIBUTES
FILE_ALL_ACCESS
FILE_GENERIC_READ
FILE_GENERIC_WRITE
FILE_GENERIC_EXECUTE
Flags: INHERITED_ACE
Name : VORDEFINIERT\Administratoren
SID : S-1-2298417664-4232053-1245072
Entry #4
Type : grant
Mask :
SYNCHRONIZE
WRITE_OWNER
WRITE_DAC
READ_CONTROL
STANDARD_RIGHTS_REQUIRED
STANDARD_RIGHTS_ALL
DELETE
file: FILE_READ_DATA, dir: FILE_LIST_DIRECTORY
file: FILE_WRITE_DATA, dir: FILE_ADD_FILE
file: FILE_APPEND_DATA, dir: FILE_ADD_SUBDIRECTORY
FILE_READ_EA
FILE_WRITE_EA
file: FILE_EXECUTE, dir: FILE_TRAVERSE
FILE_DELETE_CHILD
FILE_READ_ATTRIBUTES
FILE_WRITE_ATTRIBUTES
FILE_ALL_ACCESS
FILE_GENERIC_READ
FILE_GENERIC_WRITE
FILE_GENERIC_EXECUTE
Flags: INHERITED_ACE
Name : HAL9000\Michael
SID : S-1-2298417664-4232053-1245072-4232178-1245064-3604535
| DumpDacl_Delphi.zip | Wednesday, 29-Dec-2010 23:45:25 CET | 27K |
| DumpDacl_C.zip | Wednesday, 29-Dec-2010 23:45:25 CET | 13K |
| FileAccess.zip | Wednesday, 29-Dec-2010 23:45:27 CET | 11K |
Für die Unterstützung bei der Erstellung der Demos bedanke ich mich herzlich bei Nico Bendlin und Christian Seehase.
[1] http://msdn.microsoft.com/library/default.asp?url=/library/en-us/fileio/fs/file_security_and_access_rights.asp
[2] http://www.michael-puff.de/Artikel/2006/files/DumpDacl_Delphi.zip
[3] http://www.michael-puff.de/Artikel/2006/files/DumpDacl_C.zip
[4] http://www.michael-puff.de/Artikel/2006/files/FileAccess.zip
[5] http://msdn.microsoft.com/library/default.asp?url=/library/en-us/secauthz/security/access_control_lists.asp
[6] http://msdn.microsoft.com/library/default.asp?url=/library/en-us/secauthz/security/access_control_entries.asp
[7] http://msdn.microsoft.com/library/default.asp?url=/library/en-us/secauthz/security/how_dacls_control_access_to_an_object.asp
[8] http://msdn.microsoft.com/library/default.asp?url=/library/en-us/secauthz/security/access_control.asp
[9] http://msdn.microsoft.com/library/default.asp?url=/library/en-us/secauthz/security/getnamedsecurityinfo.asp
[10] http://msdn.microsoft.com/library/default.asp?url=/library/en-us/secauthz/security/getaclinformation.asp
[11] http://msdn.microsoft.com/library/default.asp?url=/library/en-us/secauthz/security/getace.asp