Author Topic: c++ file Operationen  (Read 11490 times)

MathiasW

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 614
  • Karma: +13/-0
    • my Arduino page
c++ file Operationen
« on: June 09, 2017, 08:26:28 PM »
Salut,

ich versuche auf dem Raspberry PI eine einfache Dateioperation auszuführen:
als erstes erstelle ich eine Datei:
Code: [Select]
touch /tmp/PanelReadDann starte ich ein Programm, welches folgende c++ Zeile ausführt:
Code: [Select]
if (fileExists("/tmp/PanelRead")){
  result = remove("/tmp/PanelRead");
  printf(" result %s\n");
}
Das Ergebnis ist immer -1 und errno liefert als Begründung "Operation not permitted"
Auch wenn ich den Aufruf von remove() durch
Code: [Select]
system(" rm /tmp/PabelRead");ersetze, erhalte ich die Fehlermeldung, dass die Operation nicht erlaubt ist.
Die Datei hat die Permission 777 und gehört pi:pi
Das c-Programm wird mit sudo ausgeführt (da ich root sein muss um das LED-Panel anzusprechen)
Im Terminal kann ich problemlos dem rm Befehl absetzen und die Datei ist weg.
Die Attribute scheinen ok zu sein.
Code: [Select]
lsattr /tmp/PanelRead
-------------e--  /tmp/PanelRead
Im Internet habe ich keine Hinweise gefunden - alles was dazu zu finden war beschreibt meinen Code ...
Die routine fileExists macht ein stat  ("/tmp/PanelRead") - Muss ich nach solch einer Abfrage warten oder ein Flag clearen? Die Datei selbst wird nicht geöffnet.

Latein == ENDE
Bin für jede Hilfe dankbar - wenn root eine Datei in /tmp nicht löschen kann, werde ich schon etwas nervös

Ciao, Mathias

boxtec-support

  • Moderator
  • Hero Member
  • *****
  • Posts: 787
  • Karma: +15/-0
    • Boxtec Web
Re: c++ file Operationen
« Reply #1 on: June 10, 2017, 10:51:39 PM »
Hallo Mathias,

Bin nicht sicher ob Dir das hilft, aber versuche mal exec() statt system(), system mag sudo gar nicht (1).

(1) https://linux.die.net/man/3/system:
Quote
..
Do not use system() from a program with set-user-ID or set-group-ID privileges, because strange values for some environment variables might be used to subvert system integrity. Use the exec(3) family of functions instead, but not execlp(3) or execvp(3). system() will not, in fact, work properly from programs with set-user-ID or set-group-ID privileges on systems on which /bin/sh is bash version 2, since bash 2 drops privileges on startup.
..

Hoffe das hilft Dir weiter.

Grüsse - Christoph

pylon

  • freakyfriday
  • Full Member
  • *
  • Posts: 158
  • Karma: +16/-0
Re: c++ file Operationen
« Reply #2 on: June 12, 2017, 09:49:03 AM »
Hallo Mathias,

hast Du mal versucht, das Programm als Root auszuführen, also nicht per sudo, sondern vorher z.B. ein
Code: [Select]
sudo su -
zu machen?
Das /tmp-Verzeichnis ist insofern speziell, als dass Dateien dort nur vom Ersteller unbenannt oder gelöscht werden dürfen (das Verzeichnis hat das Sticky-Bit gesetzt). Dabei ist irrelevant, welche Berechtigungen sonst gesetzt sind. Zum Löschen sind übrigens nicht die Datei-Berechtigungen relevant, sondern die des Verzeichnis, das die Datei enthält.

microtherion

  • freakyfriday
  • Full Member
  • *
  • Posts: 163
  • Karma: +13/-0
Re: c++ file Operationen
« Reply #3 on: June 12, 2017, 10:06:14 AM »
Das /tmp-Verzeichnis ist insofern speziell, als dass Dateien dort nur vom Ersteller unbenannt oder gelöscht werden dürfen (das Verzeichnis hat das Sticky-Bit gesetzt). Dabei ist irrelevant, welche Berechtigungen sonst gesetzt sind. Zum Löschen sind übrigens nicht die Datei-Berechtigungen relevant, sondern die des Verzeichnis, das die Datei enthält.

Der zweite Punkt stimmt auf jeden Fall. Der erste Punkt ist ein interessanter Fall:

Code: [Select]
For directories, it prevents [b]unprivileged[/b] users from removing or renaming a file in  the  directory  unless they  own  the file or the directory.
Zunächst war meine Reaktion: "Der Prozess ist root, folglich also privilegiert", aber die Linux manpage zu unlink hat mich eines Besseren belehrt:

Code: [Select]
EPERM or EACCES
              The  directory  containing pathname has the sticky bit (S_ISVTX) set and the process’s effective UID
              is neither the UID of the file to be deleted nor that of the directory containing it, and  the  pro-
              cess is not privileged (Linux: does not have the CAP_FOWNER capability).

d.h. es sieht so aus, als brauche Dein Process die obige Capability. Es sollte auch möglich sein, vor dem Löschen seteuid() aufzurufen.

MathiasW

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 614
  • Karma: +13/-0
    • my Arduino page
Re: c++ file Operationen
« Reply #4 on: June 12, 2017, 12:15:54 PM »
Salut,

vielen Dank für die Vorschläge. Als Lösung habe ich nun die aus meiner Sicht elegantere Möglichkeit gewählt, über stat die modification-time einer Datei abzufragen und sobald der Webserver die Datei mit neuem Inhalt füllt, wird dieser dann erkannt und neu gelesen.

Unabhängig davon habe ich im Programm ein
Code: [Select]
system("rm -f /tmp/x.x");eingefügt. diese Datei gehört root und ist via
Code: [Select]
sudo touch /tmp/x.xangelegt worden.
Wenn ich das Programm mit Sudo aufrufe, kann die Datei nicht gelöscht werden. Wenn ich das Programm von einer root shell aus aufrufe, kann die Datei nicht gelöscht werden. Das gleiche gilt für den c-Befehl remove(). Es kommt immer die gleiche Fehlermeldung "Operation ist nicht erlaubt". Es liegt nicht an /tmp, da ein Test mit /home/pi/x.x auch fehlschlägt
Ich habe dann einen letzten Test gemacht:
Code: [Select]
sudo mkdir /TEST
sudo chmod 777 /TEST
touch /TEST/x.x
sudo ./vdmPanel
im Programm vdmPANEL wid dann der
Code: [Select]
system("rm -f /TEST/x.x"); ausgeführt, was jetzt funktioniert. Ich werde also für das Panel ein Verzeichnis /PANEL anlegen, in dem ich die Flagfiles ablege.

Sehr verwirrend...
Ciao, Mathias