2010-03-07 10 views
19

Ich versuche, eine schreibgeschützte Datei in C unter Linux (Ubuntu) zu erstellen. Dies ist mein Code:Erstellen Sie eine Datei in Linux mit C

int fd2 = open ("/tmp/test.svg", O_RDWR|O_CREAT); 

if (fd2 != -1) { 
    //.... 
} 

Aber warum die Dateien, die ich erstellt habe ‚xr‘ -Modus? Wie kann ich es erstellen, so dass ich es an der Eingabeaufforderung selbst öffnen kann?

------xr-- 1 michael michael 55788 2010-03-06 21:57 test.txt* 
------xr-- 1 michael michael 9703 2010-03-06 22:41 test.svg* 
+2

Super Beispiel für unsafe Code. –

+2

@Michael Fouarakis: vorübergehend gibt es größere Probleme zu bewältigen, aber Sie haben Recht. O_EXCL sollte hinzugefügt werden (um zu verhindern, dass böswillige gebrochene symbolische Links verloren gehen, und um zu verhindern, dass andere Leute die Datei überlisten, wenn sie das gleiche Programm auf demselben Rechner ausführen); Der feste Name wird im Produktionscode problematisch sein, also sollte er '' mkstemp() ''oder einen Verwandten verwenden, um den Dateinamen zu erzeugen. Und die Liste geht ohne Zweifel weiter. –

Antwort

31

Sie müssen die drei Argument Form open() wenn Sie O_CREAT angeben. Wenn Sie das dritte Argument weglassen, verwendet open() den Wert, der zufällig auf dem Stapel liegt, auf dem das dritte Argument erwartet wurde. Dies ist selten eine kohärente Menge von Berechtigungen (in Ihrem Beispiel scheint es, dass Dezimal 12 = Oktal 014 war auf dem Stapel). Das dritte Argument sind die Berechtigungen für die Datei, die durch den Wert umask() geändert werden.

int fd2 = open("/tmp/test.svg", O_RDWR | O_CREAT, S_IRUSR | S_IRGRP | S_IROTH); 

Beachten Sie, dass Sie eine Datei ohne Schreibberechtigungen erstellen können (an anderen Personen oder ein anderes Verfahren), während noch in der Lage zu sein, um es von dem aktuellen Prozess zu schreiben. Es ist selten notwendig, Ausführungsbits für Dateien zu verwenden, die aus einem Programm erstellt wurden - es sei denn, Sie schreiben einen Compiler (und '.svg' Dateien sind normalerweise keine ausführbaren Dateien!).

Die S_xxxx Fahnen kommen aus <sys/stat.h> und <fcntl.h> - Sie entweder Header, um die Informationen zu erhalten, verwenden können (aber open() selbst in <fcntl.h> erklärt wird).

Beachten Sie, dass der feste Dateiname und das Fehlen von Schutzoptionen wie O_EXCL sogar die überarbeitete open() Aufruf etwas unsicher machen.

+1

Wenn Sie neuere Versionen der glibc-Header und gcc haben, kann gcc Sie davor warnen, das dritte Argument zu "öffnen" zu lassen. – caf

+0

@ Jonathan: ist etwas falsch in dem, was ich gepostet habe? Sie haben über das Folgen bösartiger gebrochener symbolischer Links und des Problems mit dem festen Namen im Produktionscode gesprochen. Was/warum sind diese Probleme? –

+1

@nvl: Lassen Sie uns sagen, dass zwei Benutzer, Bill und Joe, beide Ihr Programm zur gleichen Zeit ausführen. Beide erstellen eine Datei /tmp/test.svg ..., deren Daten verwendet werden? Nehmen wir an, Mr. Malicious arbeitet auf Ihrem Rechner und schafft es: 'ln -s/etc/passwd/tmp/test.svg'. Nun wird eines von zwei Dingen passieren, wenn Ihr Programm läuft: (1) Sie erhalten einen offenen Fehler, weil Sie nicht in/etc/passwd schreiben können (Sie sind nicht root), oder (2) Sie erhalten eine Kopie von Ihr SVG-Bild in/etc/passwd, weil Sie root sind. Beides wird normalerweise nicht als wünschenswert angesehen. Und Mr. Malicious kann auch: 'ln -s /usr/lib/security/libmalpam.so/tmp/test.svg' ... –

1

Zugriffsberechtigungen Geben Sie als dritten Parameter:

int fd2 = open("/tmp/test.svg", O_RDWR|O_CREAT, 0777); // Originally 777 (see comments) 

if (fd2 != -1) { 
    // use file descriptor 
    close(fd2); 
} 

Auf diese Weise alle Lese-, Schreib- und ausgeführt wird Berechtigungen für Benutzer, Gruppe und andere gegeben werden. Ändern Sie den 3. Parameter entsprechend Ihrer Verwendung.

+1

777 ist nicht dasselbe wie S_IRWXU | S_IRWXG | S_IRWXO. 0x777 ist zufällig dasselbe, aber es ist eine schlechte Codierungspraxis. – prewett

+3

Beachten Sie, dass weder 777 (dezimal) noch 0x777 (hex) mit dem normalen 0777 (oktal) oder 'S_IRWXU | identisch sind S_IRWXG | S_IRWXO', das dem Benutzer, der Gruppe und anderen Lese-, Schreib- und Ausführungszugriff auf eine Datei ermöglicht. Der vorherige Kommentar "0x777 ist zufällig" ist also falsch. Es entspricht: r-xrwSrwt (SGID Bit gesetzt, SVTX Bit gesetzt, plus 0567 Berechtigungen, und ich habe nicht die Geduld, das symbolisch zu schreiben - es erfordert 7 Begriffe oder zusammen). –

Verwandte Themen