Mit Java Berechtigungen im Dateisystem von Windows (ACL) auslesen

Na was für eine Erleichterung, Dateisystemberechtigungen setzten bzw. auslesen mit Powershell ist recht schwierig bzw. wenn man nicht so vertraut ist mit Powershell auch etwas kryptisch, vor Allem wenn man komplette Verzeichnisstrukturen auslesen möchte. Für solche Aufgaben eignet sich doch dann Java besser.

Ich hatte schon vor längerer Zeit nach den entsprechenden Java-Methoden Ausschau gehalten, doch nun mit Java 7 lassen sich nun endlich Dateisystemberechtigungen auslesen und sogar schreiben. Das bedeutet aber auch, dass das nachfolgende Tutorial nicht mit Java 6 funktioniert.

Grundlegendes zu den Dateisystemberechtigungen

Eine Datei bzw. ein Verzeichnis hat eine sogenannte Access Control List (AC) (deutsch Zugriffssteuerungsliste) und in dieser Liste befinden sich dann die vergebenen Dateisystemberechtigungen. Eine Dateisystemberechtigung besteht (zumindes unter Microsoft Windows) aus den folgenden Angaben:

  • Benutzer/Gruppe
  • Zugriffstyp (Zulassen, Verweigern)
  • Berechtigung (Schreiben, Lesen, Löschen, …)
  • Vererbung (Nur dieser Ordner, Ordner und Unterordner, etc.)

Mit Microsoft Mitteln setzt man Berechtigungen im Dateisystem mit einem Rechtsklick auf den ausgewählten Ordner/Eigenschaften im Reiter Sicherheit. Beim Klicken auf Erweitert werden dann alle Dateisystemberechtigungen der ACL angezeigt:

So werden die Dateisystemberechtigungen in Windows eingestellt / angezeigt
So werden die Zugriffrechte in Windows eingestellt / angezeigt

Das Setzten und Auslesen von Dateisystemberechtigungen unter Windows sieht zunächst einfach aus, aber der Teufel steckt im Detail. Denn das so simple Recht wie „Lesen“ besteht in Wahrheit aus folgenden einzelnen Zugriffsberechtigungen:

  • Ordner auflisten/Daten lesen
  • Attribute lesen
  • Erweiterte Attribute lesen
  • Berechtigungen lesen
  • Synchronisieren

Noch verrückter wird es, wenn man die Vererbung hinzu nimmt, denn das Recht „Lesen und Ausführen“ zum Beispiel ist das selbe wie „Ordnerinhalt auflisten“. Beide unterscheiden sich nur durch Ihre Vereerbung. Nun wer auch immer Berechtigungen im Dateisystem mit Java oder auch anderen Programmiersprachen auslesen bzw. setzten will muss sich dort wohl etwas länger einarbeiten. Deswegen zurück zum Kern:

Tutorial zum Lesen von Dateisystemberechtigungen (ACL) mit Java 7 unter Windows

Folgende stark gekürzte Java Klasse zeigt wie Berechtigungen ausgelesen werden können:

public class Ico_GetACL {
	public static void main(String[] args) throws IOException {
		new Ico_GetACL().getACL("C:\\Icomundo\\test");
	}
	private FileSystem fs = FileSystems.getDefault();
	public void getACL(String path) throws IOException{
		System.out.println("ACLs for: "+path);
		Path p = fs.getPath(path);
		AclFileAttributeView view =
			Files.getFileAttributeView(p, AclFileAttributeView.class);
		List acl = view.getAcl();
		System.out.println("Besitzer: "+view.getOwner());
		for(AclEntry ace:acl){
			System.out.print(ace.type().name()+"\t");
			//Zugriffstyp Allow,Deny,...
			System.out.println(ace.principal().getName()); //Benutzer
			System.out.print("\tVererbung: ");
			System.out.println(Inheritance.getInheritance(ace.flags()));
			System.out.print("\tVererbungsflags: ");
			for(AclEntryFlag aef:ace.flags())
			System.out.print(" "+aef.name());
			System.out.print("\n");
			System.out.print("\tRecht: "+Permission.getPermission(
				ace.permissions(), ace.flags(), true).name()+"\n");
			System.out.print("\tRechte einzeln: ");
			for(AclEntryPermission aep:ace.permissions())
			System.out.print(" "+aep.name());
			System.out.print("\n");
			System.out.println("-");}}}

Die Ausgabe dieser Java Klasse in der Konsole (analog zum Verzeichnis aus dem Bild oben) sieht dann so aus:

ACLs for: C:\Icomundo\test
Besitzer: Udo-PC\Udo (User)
ALLOW	Udo-PC\Administrator
	Vererbung: ThisFolderAndSubFolderAndFiles
	Vererbungsflags:  DIRECTORY_INHERIT FILE_INHERIT
	Recht: special
	Rechte einzeln:  READ_ACL READ_DATA SYNCHRONIZE WRITE_DATA READ_ATTRIBUTES READ_NAMED_ATTRS EXECUTE
-
ALLOW	Udo-PC\Udo
	Vererbung: ThisFolderAndSubFolderAndFiles
	Vererbungsflags:  DIRECTORY_INHERIT FILE_INHERIT
	Recht: full
	Rechte einzeln:  READ_ACL WRITE_ATTRIBUTES READ_DATA DELETE_CHILD DELETE WRITE_DATA READ_ATTRIBUTES WRITE_ACL WRITE_OWNER EXECUTE SYNCHRONIZE APPEND_DATA READ_NAMED_ATTRS WRITE_NAMED_ATTRS
-

Den Besitzer eines Ordnders mit Java ermitteln

Vielleicht im Quellcode etwas untergegangen, aber schnell noch angefügt: Mit view.getOwner(); erhält man gleich noch den Besitzer eines Verzeichnisses mit.

Die Java Klassen Inheritance und Permission

sind natürlich schnelle Eigenprogrammierungen um ein paar „simple“ Dinge nachzubilden, denn das Recht „Lesen“ erhält man nicht so einfach da es aus mehreren Einzelberechtigungen besteht. Auch die Vererbung ist eine Verknüpfung der AclEntryFlag’s.

Die beiden Java Enum Klassen können hier herruntergeladen werden, wobei ich nochmal ausdrücklich erwähne, dass diese keinen Anspruch auf Perfektion erheben. Ich selbst plane ein Tool zum Auslesen von Berechtigungen einer ganzen Verzeichnisstruktur, da werde ich ja merken wo noch Fehler drin sind. Für eure Rückmeldungen wäre ich natürlich genauso dankbar.