Sebastian Becker: Permission denied

Hallo,

mein Account bei Hosteurope zeigt seit kurzem folgendes merkwürdige Verhalten, erläutert an einem Beispiel: Ich habe im Hauptverzeichnis per FTP ein File test.php abgelegt mit folgendem Code ...

<?php
// Testfile
$file='test.htm';

// Existenz prüfen
if(file_exists($file))echo "file $file exists<br>";

// File löschen
if(unlink($file))echo "file $file removed";
?>

sowie ein zu löschendes File test.htm, jeweils mit chmod 777. Beim Aufruf des PHP-Files erhalte ich folgende Ausgabe samt typischer Fehlermeldung ...

file test.htm exists
Warning: unlink(test.htm): Permission denied in /is/htdocs/61037/www.meineurl.de/test.php on line 4

und die Löschung wird nicht durchgeführt.

Ein solches Serververhalten ist natürlich auch keine günstige Voraussetzung für den Betrieb erheblich komplizierterer Skripte. So kann ich derzeit beispielsweise weder eine PHP-Bildergalerie noch einen PHP-Filemanager sinnvoll betreiben.

Das Problem liegt - laienhaft ausgedrückt - vermutlich darin, daß PHP vom Server nicht als Eigentümer von auf diesem abgelegten Files angesehen wird und daß dieser daher bestimmte Aktionen wie das Löschen oder Setzen von Rechten mit PHP nicht gestattet.

Vielleicht kann das jemand fachmännischer erklären - oder widerlegen - und vor allem Abhilfe anbieten?

Danke für alle Hinweise, Grüße,

Sebastian Becker

  1. Hello,

    Hier unterscheiden sich die Betriebssysteme.

    welches Recht benötigt man zum Anlegen und Löschen eines Files unter Linux?

    Man muss in der zugehörigen Verzeichnistabelle schreiben dürfen.

    Harzliche Grüße aus http://www.annerschbarrich.de

    Tom

    --
    Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
    Nur selber lernen macht schlau
    1. Hallo, Tom,

      Hier unterscheiden sich die Betriebssysteme.
      welches Recht benötigt man zum Anlegen und Löschen eines Files unter Linux?
      Man muss in der zugehörigen Verzeichnistabelle schreiben dürfen.

      ich weiß nicht so recht, was das bedeutet und was ich mit dieser Information anfangen soll. Ist das ein Lösungsansatz?

      Grüße,

      Sebastian

      Der Server ist übrigens ein Apache und ursprünglich hatte alles funktioniert. Das Problem trat zum ersten Mal auf, nachdem ich im Hosteurope-KIS-Konfigurationsmenü Files gelöscht habe, die ich weder mit FTP noch mit PHP löschen konnte.

      Dazu gibt es folgende FAQ:

      Warum kann ich Dateien nicht per FTP löschen?

      Gelegentlich ist es nicht möglich, Dateien die sich im eigenen Webspace befinden per FTP zu löschen. Hier wird das "Warum?" und das "Wie trotzdem?" erklärt :o)

      Die Rechtestruktur des Webservers sieht vor, dass der Webserver unter einem anderen Benutzer läuft als Ihr FTP-Zugang. Dadurch kann man per FTP keine Dateien löschen, die "jemand anders", also z.B. ein Skript aus Ihrem Webauftritt, erzeugt hat. Dies ist nur wieder per Skript oder über das KIS machbar.

      1. Hello,

        Hier unterscheiden sich die Betriebssysteme.
        welches Recht benötigt man zum Anlegen und Löschen eines Files unter Linux?
        Man muss in der zugehörigen Verzeichnistabelle schreiben dürfen.

        ich weiß nicht so recht, was das bedeutet und was ich mit dieser Information anfangen soll.

        Du sollst darüber nachdenken und Dir klar darüber werden, wer für den Fileservice auf Deiner Maschine zuständig ist. Üblicherweise ist das nicht der Webswerver, sondern das Betriebssystem.

        Ist das ein Lösungsansatz?

        Wenn ich beim dritten Satz nicht vergessen hätte, dass der sich auf Unix/Linux bezieht, wäre es sogar schon die Lösung. Aber es stand ja im zweiten, und soviel Mitdenken hatte ich erwartet. ;-)

        Den Rest hat Dir Christian nochmal vorgeführt.

        Wenn Du mit PHP-Modul eine Datei löschst, dann ist der ausführende User (aus der Sicht des Betriebssystems) i.d.R. der Webserver. Der nennt sich als User dann z.B. 'apache' oder 'wwwrun'. Andere Namen sind natürlich auch möglich, aber das sind die meistens benutzten.

        Dieser User muss nun Schreibrechte auf die Verzeichnistabelle des Verzeichnisses haben. Es müssen für ihn also mindestens '-wx' eingerichtet sein. Das x benötigt er, dass er das Verzeichnis in den qualifizierten Pfad (kanonisch) aufnehmen darf, das w benötigt er, dass er den Dateinamen in die Tabelle eintragen darf oder ihn dort wieder entfernen darf. Wenn er die Verzeichnistabelle auch lesen will, muss er dafür auch das r-Recht besitzen. Nur dann kann er die Namen der Dateien im Verzeichnis direkt ermitteln. Ohne das r-Recht könnte er auf die Datein nur zugreifen, wenn der deren Namen genau kennt.

        Ob er in der Datei selber etwas ändern darf, regeln dann die Rechte, die an der Datei selbst vermerkt werden. Das sind übringens niccht "Die Rechte der Datei" und schon gar nicht die "CHMODs". Es sind die Rechte von Eigentümer (Owner = u), Hauptgruppe (Group = g) und Gästen (Other = o) an der Datei.

        Wenn für die Datei also     rwx r-x ---    vermerkt ist, dann darf der Owner der Datei in diese hineinschauen (read), in diese hineinschreiben (write) und diese ausführen lassen (eXecute).

        Bei Verzeichnissen würde es bedeuten:

        Der Eigentümer darf die Verzwichnistabelle (also die Namen der darin vermerkten Ressourcen) auslesen, er darf sie verändern, also Ressourcen hinzufügen, umbenennen, löschen, und er darf den Verzeichnisnamen für die Pfadbildung zu tieferen Ressourcen benutzen.

        Wenn Dir das alles nicht hilft, dann versuch erst einmal, ein paar gute Seiten über Linux zu ergooglen. Grundverständnis über das Filesystem des Hosts ist Voraussetzung für Programme in PHP, die mit Files und Ressourcen arbeiten.

        Die nächste Hürde, die Du ggf. zu knacken hast, könnte dann der Safe Mode von PHP sein.

        Harzliche Grüße aus http://www.annerschbarrich.de

        Tom

        --
        Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
        Nur selber lernen macht schlau
        1. Hallo, Tom,

          vielen Dank für Deine ausführlichen Erläuterungen, die ein erhellendes Licht auf die Geheimnisse von Server-Verzeichnissystemen werfen  ;-)  ...

          Da ich die Sache aber auch pragmatisch angehen will, hier nun meine konkrete Frage: Wie kann ich dafür sorgen, daß ich wieder mit PHP alle von mir mit PHP oder per FTP-Upload angelegten Datein ändern oder löschen sowie neue anlegen kann?

          Dazu müsste doch - entweder von mir oder vom Serverbetreiber - irgendwo eine Einstellung vorgenommen werden, die mich wieder zum Eigentümer der entsprechenden Files macht, oder??? Und wie konnte es überhaupt dazu kommen, daß ich diese Rechte plötzlich nicht mehr besitze?

          Warum müssen einfache Dinge denn immer so kompliziert sein?

          Grüße,

          Sebastian

          1. Hello,

            Dazu müsste doch - entweder von mir oder vom Serverbetreiber - irgendwo eine Einstellung vorgenommen werden, die mich wieder zum Eigentümer der entsprechenden Files macht, oder??? Und wie konnte es überhaupt dazu kommen, daß ich diese Rechte plötzlich nicht mehr besitze?

            Dafür könnte es verschiedene Gründe geben.
            Wir unterscheiden hier i.d.R. drei Bentuzer:

            ftp-Bentuzer
              Webserver (PHP-"daemon")
              System-Benutzer (= Konsolen-User wenn Du auch einen ssh-Zugang hast)

            Wenn nun der Webserver in Deiner Document Root ein eigenes Verzeichnis anlegt, dann wird er als Eigentümer eingetragen. Dein FTP-User darf dann ggf. nicht mehr darauf zugreifen.

            Harzliche Grüße aus http://www.annerschbarrich.de

            Tom

            --
            Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
            Nur selber lernen macht schlau
            1. Hello, Tom,

              Wir unterscheiden hier i.d.R. drei Bentuzer:
              ftp-Bentuzer
              Webserver (PHP-"daemon")
              System-Benutzer (= Konsolen-User wenn Du auch einen ssh-Zugang hast)

              Wenn nun der Webserver in Deiner Document Root ein eigenes Verzeichnis anlegt, dann wird er als Eigentümer eingetragen. Dein FTP-User darf dann ggf. nicht mehr darauf zugreifen.

              So war es zunächst - jetzt ist es genau umgekehrt: ich kann mit FTP hochgeladene Dateien nicht mehr mit PHP löschen ...

              Grüße,

              Sebastian

              1. Moin Sebastian,

                So war es zunächst - jetzt ist es genau umgekehrt: ich kann mit FTP hochgeladene Dateien nicht mehr mit PHP löschen ...

                Ich würde mal sagen das ist doch klar! Mit deinem FTP Login bist du eine anderer User als der User welcher als PHP User läuft.

                Wenn du Dateien mit dem PHP erstellst dann gib ihnen mit chmod die Rechte 666 rw-rw-rw  (666) dann knast du sie auch als ftp user löschen

                http://www.php.net/manual/de/function.chmod.php

                regds
                Mike©

                --
                Freunde kommen und gehen. Feinde sammeln sich an.
                1. Hello,

                  Wenn du Dateien mit dem PHP erstellst dann gib ihnen mit chmod die Rechte 666 rw-rw-rw  (666) dann knast du sie auch als ftp user löschen

                  Das nützt ihm nichts, denn wie ich schon erwähnte, ist das Erzeugungsrecht und das Löschrecht für Dateien bei Unix/Linux im w-Recht des _Verzeichnisses_ verankert.

                  Die w-Rechte der Dateien beziehen sich nur auf deren _Inhalt_ aber nicht auf die "Hülle"

                  Es wäre auch intelligenter, sich mittels der posix_* Funktionen oder auch mittels system() (je nachdem, was funktioniert) Überblick über die User und Gruppen zu verschaffen. Und dann sollte er jeweils eine gemeinsame Gruppe für die Fiels des FTP-Users und des Webservers einstellen und dieser die passenden Rechte einräumen.

                  Beispiel für die Ermittlug der Daten des ausführenden Prozesses:

                  <?php   #### userinfo.php ####

                  $uid = posix_geteuid();

                  $_user = posix_getpwuid ( $uid );

                  echo "<pre>\n";
                  print_r($_user);
                  echo "</pre>\n";

                  ?>

                  Ich kenne die nun auch noch nicht auswendig. Nächster Schritt sollte also sein, die Gruppen herauszufinden, zu denen der Webserver gehört, und dann diejenigen, zu denen der FTP-User gehört.

                  Man muss dazu leider immmer mit den Namen und den IDs jonglieren.

                  Harzliche Grüße aus http://www.annerschbarrich.de

                  Tom

                  --
                  Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
                  Nur selber lernen macht schlau
                  1. Hello,

                    <?php  #### groups.php ###

                    $_grouplist = posix_getgroups();

                    echo "<h3>Gruppenliste f&uuml;r den aktuellen Prozess</h3>";
                      echo "<pre>\n";
                      print_r($_grouplist);
                      echo "</pre>\n";

                    foreach($_grouplist as $key => $val)
                      {
                        $_group = posix_getgrgid($val);
                        $_grouplist[$key] = $_group;
                      }

                    echo "<h3>Liste der Gruppenmitglieder</h3>";

                    echo "<pre>\n";
                      print_r($_grouplist);
                      echo "</pre>\n";

                    ?>

                    Bah nochmal ein bisschen gebastelt.
                    Sofern das überhaupt auf dem Server und dann unter dem Safe_Mode läuft, sollte das kleine Script überblick über die Gruppen geben, die in Frage kommen. Nun muss man nur eine suchen, in der man als FTP-User enthalten ist und auch eine Gruppe des Prozesses.

                    Harzliche Grüße aus http://www.annerschbarrich.de

                    Tom

                    --
                    Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
                    Nur selber lernen macht schlau
                    1. Hallo, Tom,

                      hier die Ausgabe von groups.php ...

                      Gruppenliste für den aktuellen Prozess
                      Array (
                      [0] => 99
                      )

                      Liste der Gruppenmitglieder
                      Array (
                      [0] => Array (
                      [name] => nobody
                      [passwd] => x
                      [members] => Array()
                      [gid] => 99
                      )
                      )

                      Bei der Interpretation bin ich leider wiederum zunächst mal überfordert ...

                      Danke für Deine konstruktive Hilfe.

                      Grüße,

                      Sebastian

                      1. Hello,

                        Hallo, Tom,

                        hier die Ausgabe von groups.php ...

                        Gruppenliste für den aktuellen Prozess
                        Array (
                        [0] => 99
                        )

                        Liste der Gruppenmitglieder
                        Array (
                        [0] => Array (
                        [name] => nobody
                        [passwd] => x
                        [members] => Array()
                        [gid] => 99
                        )
                        )

                        Bei der Interpretation bin ich leider wiederum zunächst mal überfordert ...

                        Tja, sieht so aus, als ob der Webserver als Prozessinhaber (setze ich mal voraus) nur zur Gruppe nobody gehört, sich also der Provider für eine User-Webserver-Kombination überhaupt keine Mühe gemacht hat.

                        Da Du selber nicht Mitglied der Gruppe nobody bist, darfst Du auch Deine Dateien nicht dieser Gruppe zugänglich machen. Du hast dann also keine andere Chance, als die Rechte für 'Others' zu verwenden, oder Dich eines eigenen Uploadscriptes laut meiner Beschreibung im Safe-Mode-Script zu bedienen.

                        Hier mal zum Vergleich die Ausgabe des Scriptes auf einem Testserver:

                        Gruppenliste für den aktuellen Prozess
                        Array
                        (
                            [0] => 505
                            [1] => 500
                            [2] => 501
                            [3] => 504
                        )

                        Liste der Gruppenmitglieder
                        Array
                        (
                            [0] => Array
                                (
                                    [name] => wwwrun
                                    [passwd] =>
                                    [members] => Array
                                        (
                                            [0] => wwwrun
                                        )

                        [gid] => 505
                                )

                        [1] => Array
                                (
                                    [name] => szene
                                    [passwd] => *
                                    [members] => Array
                                        (
                                            [0] => thomas
                                            [1] => wwwrun
                                            [2] => fabian
                                            [3] => holger
                                            [4] => katja
                                            [5] => thomasm
                                        )

                        [gid] => 500
                                )

                        [2] => Array
                                (
                                    [name] => websites
                                    [passwd] =>
                                    [members] => Array
                                        (
                                            [0] => wwwrun
                                            [1] => thomas
                                            [2] => carsten
                                        )

                        [gid] => 501
                                )

                        [3] => Array
                                (
                                    [name] => praktikum
                                    [passwd] => *
                                    [members] => Array
                                        (
                                            [0] => thomas
                                            [1] => katja
                                            [2] => wwwrun
                                            [3] => thomasm
                                        )

                        [gid] => 504
                                )

                        )

                        Da gibt es einige Schnittmengen. Und wenn man den Webserver mittels open_basedir davon abhält, jeweils außerhalb der jeweiligen Document Root || Upload Tmp Dir || Session.save_path zu hantieren, bekommt man auch einigermaßen Struktur in die Geschichte.

                        Harzliche Grüße aus http://www.annerschbarrich.de

                        Tom

                        --
                        Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
                        Nur selber lernen macht schlau
                        1. Hallo, Tom,

                          vielen Dank für Deine kompetenten Hinweise.

                          Ich muß allerdings gestehen, daß ich immer noch ein Brett vorm Kopf habe und nicht weiß, wie ich nun den ursprünglichen Zustand, bei dem es mit dem Anlegen und Löschen von Files klappte, wiederherstellen kann.

                          Ich habe ja nun wirklich keine Sonderwünsche, sondern möchte nur als Anwender ohne Linux-Spezialkenntnisse selbstvertändliche Aktionen auf dem Server auführen. Es ist mir nach wie vor unverständlich, warum dies nicht möglich ist.  ;-(

                          Die Server Hotline hat auf meine entsprechende Anfrage gar nicht geantwortet - so gesehen kann ich von Hosteurope nur abraten ...

                          Grüße,

                          Sebastian

                          1. Hello,

                            zugegeben nicht immer ganz einfach.

                            Das einfachste wird sein, du überlegst Dir, wie Du alle Dateien herunterladen kannst(mal per FTP, mal per Downloadscript) und dann versuchst Du auf ähnliche Weie, den ganzen Rotz zu löschen, baust Dir ein einheitliches Uploadscript, und dann lädst Du in Zukunft Dateien nur noch mittels des Uploadscripters hoch.

                            Verzeichnisse Anlegen selbstvertständlich auch damit.

                            Das hat den Vorteil, dass alle Verzeichnisse und Dateien nur noch dem Webserver gehören.

                            Sie sind ann durchgänging benutzbar.

                            Harzliche Grüße aus http://www.annerschbarrich.de

                            Tom

                            --
                            Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
                            Nur selber lernen macht schlau
  2. 你好 Sebastian,

    Das Problem liegt - laienhaft ausgedrückt - vermutlich darin, daß PHP vom
    Server nicht als Eigentümer von auf diesem abgelegten Files angesehen wird
    und daß dieser daher bestimmte Aktionen wie das Löschen oder Setzen von
    Rechten mit PHP nicht gestattet.

    Nee, PHPs unlink() ist nur ein Wrapper um den Systemcall unlink(). Und der
    schlaegt fehl und gibt diesen Fehlerstatus zurueck.

    Vielleicht kann das jemand fachmännischer erklären - oder widerlegen - und
    vor allem Abhilfe anbieten?

    Hat der Webserver Zugriffsrechte auf das Verzeichnis, in dem die Datei
    liegt? Die braucht er naemlich:

    ckruse@skuld tmp $ mkdir test
    ckruse@skuld tmp $ touch test/test.html
    ckruse@skuld tmp $ chmod 666 test/test.html
    ckruse@skuld tmp $ chmod 000 test
    ckruse@skuld tmp $ rm test/test.html
    rm: Aufruf von lstat für ,,test/test.html" nicht möglich: Keine Berechtigung
    ckruse@skuld tmp $ chmod 755 test
    ckruse@skuld tmp $ rm test/test.html
    ckruse@skuld tmp $

    再见,
    CK

    1. Hallo, Christian,

      Hat der Webserver Zugriffsrechte auf das Verzeichnis, in dem die Datei liegt?

      keine Ahnung - wie soll ich das herausfinden? Ich habe nur gemieteten Space bei einem Massenprovider und habe nichts an den Servereinstellungen geändert, konnte dies auch gar nicht weil ich keinen Zugriff auf dessen Parameter habe ...

      Grüße,

      Sebastian

      1. 你好 Sebastian,

        Hat der Webserver Zugriffsrechte auf das Verzeichnis, in dem die Datei
        liegt?

        keine Ahnung - wie soll ich das herausfinden?

        Guck dir halt die Modes des Verzeichnisses an, in dem die Datei liegt.

        再见,
        CK