UNIXwork

Tags

c dav unix shell linux xattr solaris links x11 java rant fun webdav sync gnome apple benchmark network ldap oracle analytics xnedit macos windows graalvm bsd curl mac apache wtf virtualbox microsoft zfs sparc tomcat rhel freebsd arm

Kleine Lib für Extended Attributes

29. November 2024

Wer eine plattformunabhängige Lösung für den Zugriff auf Extended Attributes benötigt, für den habe ich hier eine kleine "Bibliothek", bestehend aus einer .c und einer .h Datei. Lizenz ist 0BSD, daher kann jeder den Code verwenden wie er will.

Aktuell werden Linux, FreeBSD, Solaris und macOS unterstützt. Eine Implementierung, die unter Windows Alternate Data Streams verwendet, kommt vermutlich noch.

Extended Attributes Teil 10: Windows Syscalls

10. Dezember 2019

Für den Zugriff auf Alternate Data Streams benötigt man unter Windows keine speziellen Syscalls, da die Auswahl des Streams ein Teil des Dateipfades ist. Daher kann man z.B. auch mit fopen oder vermutlich jeder ähnlichen Funktion in anderen Programmiersprachen auf einen anderen Stream zugreifen.

FILE *f = fopen("test.txt:stream2", "w");
fprintf(f, "Hello ADS\n");    
fclose(f);

Was jedoch nicht so einfach geht ist, eine Liste aller Streams einer Datei zu erhalten. Zum Einsatz kommen dabei die Funktionen FindFirstStreamW und FindNextStreamW. Diese funktionieren ähnlich wie die Funktionen zum Auflisten von Verzeichniseinträgen (FindFirstFileW, FindNextFileW). Hier ein Beispiel, wie die Funktionen benutzt werden:

#include <stdio.h>
#include <windows.h>

int main(int argc, char** argv) {

	WIN32_FIND_STREAM_DATA findData;

	HANDLE h = FindFirstStreamW(L"test.txt", FindStreamInfoStandard, &findData, 0);
	if(h == INVALID_HANDLE_VALUE) {
    	return 1;
	}

	do {
    	printf("%S\n", findData.cStreamName);
	} while(FindNextStreamW(h, &findData));

	return 0;
}

Das Format von cStreamName ist :streamname:$streamtype. Streamtype ist in der Regel immer DATA (ich kenne kein Beispiel, in dem dies nicht der Fall ist). Für den Fall, dass die Datei test.txt in dem Beispiel einen zweiten Stream mit dem Namen mystream hat, wäre die Ausgabe folgendermaßen:

::$DATA
:mystream:$DATA

Extended Attributes Teil 9: Windows Commandline Tools

09. Dezember 2019

Windows unterstützt Extended Attributes in Form von Alternate Data Streams (ADS). Ähnlich wie unter Solaris sind Extended Attributes damit keine einfachen Key/Value-Paare, sondern Datei-Streams. Jede Datei hat einen Haupt-Stream mit dem Namen :$DATA. Daneben können aber weitere Streams für eine Datei existieren.

Zugegriffen wird auf ein Attribut bzw. Alternate Data Stream, in dem an den Dateinamen der Stream-Name, getrennt durch einen Doppelpunkt, angehängt wird.

> echo Hello World > test.txt

> type test.txt
Hello World

> echo my attribute value > test.txt:myattribute

> type test.txt:myattribute
my attribute value

Auf den eigentlichen Dateiinhalt kann auch mit dem Stream-Namen :$DATA zugegriffen werde, was auch schon Ursache für Sicherheitslücken war. Den IIS konnte man so austricksen und den Inhalt von ASP-Dateien erhalten, in dem man ::$DATA an die URL angehangen hat.

Da der Stream Teil des Dateipfades ist, kann eigentlich mit jedem beliebigen Programm darauf zugegriffen werden, z.B. auch mit Notepad:

> notepad test.txt:myattribute

Lustigerweise funktioniert dies nicht in den Powershell-Cmdlets. Diese haben jedoch Parameter für den Zugriff auf ADS. Z.B. kann Get-Item alle Streams einer Datei auflisten:

PS D:\> Get-Item -path test.txt -stream *

PSPath        : Microsoft.PowerShell.Core\FileSystem::D:\test.txt::$DATA
PSParentPath  : Microsoft.PowerShell.Core\FileSystem::D:\
PSChildName   : test.txt::$DATA
PSDrive       : D
PSProvider    : Microsoft.PowerShell.Core\FileSystem
PSIsContainer : False
FileName      : D:\test.txt
Stream        : :$DATA
Length        : 14

PSPath        : Microsoft.PowerShell.Core\FileSystem::D:\test.txt:myattribute
PSParentPath  : Microsoft.PowerShell.Core\FileSystem::D:\
PSChildName   : test.txt:myattribute
PSDrive       : D
PSProvider    : Microsoft.PowerShell.Core\FileSystem
PSIsContainer : False
FileName      : D:\test.txt
Stream        : myattribute
Length        : 21

Extended Attributes Teil 8: macOS Syscalls

10. Dezember 2017

Für den Zugriff auf Extended Attributes hat macOS die Syscalls listxattr, getxattr, setxattr und removexattr. Sie heißen genauso wie die Linux-Syscalls und funktionieren auch fast genauso, nur haben sie ein paar Parameter für Options mehr. Die Syscalls finden sich im Header sys/xattr.h.

Um den Inhalt eines Attributs zu erhalten, benutzen wir den Syscall getxattr:

ssize_t
getxattr(const char *path, const char *name, void *value, size_t size,
		u_int32_t position,
		int options);

Dabei gibt man den Dateipfad, den Namen des Attributs, einen Pointer auf einen Buffer sowie dessen Größe an. Wie im vorherigen Artikel erwähnt, haben macOS Extended Attributes keinen Namespace, daher ist name ein frei wählbarer Name. Mit value und size gibt man einen vorher allozierten Puffer und seine Größe an. Falls value NULL ist, wird von der Funktion nur die Länge des Inhalts zurück gegeben. Der Parameter position funktioniert nicht mit allen Typen von Attributen und sollte daher 0 sein. Der Parameter options kann abgesehn von 0 noch XATTR_NOFOLLOW oder XATTR_SHOWCOMPRESSION sein.

char *buf = malloc(1024);
ssize_t attrlen = ("file.txt", "myattribute", buf, 1024, 0, 0);
if(attrlen > 0) {
	printf("myattribute: %.*s\n", (int)attrlen, buf);
}

Attribute hinzufügen oder verändern geht mit setxattr.

int setxattr(const char *path, const char *name, void *value, size_t size,
		u_int32_t position,
		int options);

position sollte auch hier wieder 0 sein. Bei den options gibt es wieder XATTR_NOFOLLOW und die interessanten Options XATTR_CREATE, um zu erzwingen, dass das Attribut nur gesetzt wird, falls es noch nicht existiert, oder XATTR_REPLACE, um nur den Inhalt eines bereits existierenden Attributs zu ändern.

char *value = "Hello World!";
setxattr("file.txt", "myattribute", value, strlen(value), 0, 0);

Alle existierenden Attribute auflisten geht mit listxattr.

ssize_t listxattr(const char *path, char *namebuf, size_t size, int options);

Dies schreibt in den vorher allozierten Buffer die Namen aller Attribute, getrennt durch ein 0-Byte. Hier findet sich ein Beispielprogramm, welches alle Attribute einer Datei auflistet.

Extended Attributes Teil 7: macOS Commandline Tools

09. Dezember 2017

Unter macOS sind Extended Attributes wie unter den meisten Betriebsystemen einfache name/value-Paare. Im unterschied zu Linux oder FreeBSD haben die Attribute keinen Namespace wie user oder system sondern einfach nur einen frei wählbaren Namen.

Extended Attributes können mit dem Tool xattr angezeigt und modifiziert werden. Außerdem kann auch ls Extended Attributes anzeigen. Eine kleine Übersicht über xattr:

Namen aller Attribute oder oder mehrerer Dateien auflisten:

xattr file ...

Value eines Attributs ausgeben:

xattr -p attr_name file ...

Attribut setzen:

xattr -w attr_name attr_value file ...

Attribut entfernen:

xattr -d attr_name file ...

Alle Attribute entfernen:

xattr -c file ...

Außerdem zeigt ls -l@ an, ob und welche Attribute eine Datei hat.

Ein kleines Beispiel:

$ echo "hello" > test.txt
$ rm test.txt 
$ echo "Hello World" > hello.txt
$ echo test > test.txt
$ xattr -w mime_type "text/plain" hello.txt 
$ xattr -w author Olaf hello.txt 
$ xattr -w testxattr testvalue test.txt 
$ ls -l@
total 16
-rw-r--r--@ 1 olaf  staff  12  9 Dez 19:18 hello.txt
	author	 4 
	mime_type	10 
-rw-r--r--@ 1 olaf  staff   5  9 Dez 19:18 test.txt
	testxattr	 9 
$ xattr -p mime_type hello.txt 
text/plain

Positiv ist, dass das macOS tar Extended Attributes im Archiv speichert. Auch cp kopiert sie standardmäßig. Insgesammt scheinen Extended Attributes unter macOS generell ein lebendigeres Feature als unter anderen Betriebsystemen zu sein, denn sie werden vom Finder oder anderen Programmen auch benutzt.

Weiter