PHP copy von HTTP_POST_FILES: permission denied
Peter Pan
- php
Hallo zusammen,
eine Frage zu PHP4.3.9 (läuft auf einem Fecora Core 3 mit Apache) im Zusammenhang mit dem copy-Befehl:
Wenn ich folgendes versuche:
// upload handling
$tmpfile=$HTTP_POST_FILES['file']['tmp_name'];
$destfilename="/var/www/html/db/" . "1-13.sql";
copy($tmpfile, $destfilename);
bekomme ich in den Apache-Logs immer folgendes zu sehen:
PHP Warning: copy(/var/www/html/db/1-13.sql): failed to open stream: Permission denied in /var/www/html/db/submit.php on line 111, referer: http://localhost/db/submit.html
Was mich dabei sehr stutzig macht ist, dass das Directory /var/www/html/db world-writable ist; wie folgt:
drwxrwxrwx 2 apache apache 4096 Nov 16 19:44 .
(und auch der user apache sowie die Gruppe apache auch Schreibrechte haben).
Mit dem o.a. code kann man problemlos in /tmp schreiben; und ich frage mich, wieso. /tmp ist auch world-writable:
76 drwxrwxrwt 22 root root 69632 Nov 16 20:24 /tmp
Selbst wenn ich (den einzigen Unterschied, das -t Flag setze in /var/www/html/db für others), dann kommt immer noch der Fehler.
Weiss jemand Rat?
Vielen Dank schon jetzt für eure Bemühungen!
Hello,
Wenn ich folgendes versuche:
// upload handling
$tmpfile=$HTTP_POST_FILES['file']['tmp_name'];
$destfilename="/var/www/html/db/" . "1-13.sql";
copy($tmpfile, $destfilename);bekomme ich in den Apache-Logs immer folgendes zu sehen:
PHP Warning: copy(/var/www/html/db/1-13.sql): failed to open stream: Permission denied in /var/www/html/db/submit.php on line 111, referer: http://localhost/db/submit.html
Was steht denn drin in $HTTP_POST_FILES?
Lass Dir das mal ausgeben nach dem Upload mit
echo "<pre>\n">;
echo htlmentities(print_r($HTTP_POST_FILES,true));
echo "</pre>\n">;
Und dann lies Dir auf jeden fall alle Kapitel durch, die Du über die Links zu
http://de.php.net/manual/de/ini.sect.data-handling.php#ini.register-globals erreichn kannst.
Harzliche Grüße aus http://www.annerschbarrich.de
Tom
Hi Tom,
Was steht denn drin in $HTTP_POST_FILES?
Lass Dir das mal ausgeben nach dem Upload
nach einem
echo htmlentities(print_r($HTTP_POST_FILES,true));
bekomme ich folgendes:
Array
(
[file] => Array
(
[name] => script.sql
[type] => text/x-sql
[tmp_name] => /tmp/phpfXPrz3
[error] => 0
[size] => 793
)
)
(also scheint mit dem HTTP-Post alles geklappt zu haben).
Das Problem ist wahrscheinlich ein Rechteproblem; ich weiss nur nicht welches, da das Zielverzeichnis world-writable ist.
Hast Du noch eine Idee?
Vielen Dank!
Hello,
Was steht denn drin in $HTTP_POST_FILES?
Lass Dir das mal ausgeben nach dem Uploadnach einem
echo htmlentities(print_r($HTTP_POST_FILES,true));
bekomme ich folgendes:Array
(
[file] => Array
(
[name] => script.sql
[type] => text/x-sql
[tmp_name] => /tmp/phpfXPrz3
[error] => 0
[size] => 793
))
(also scheint mit dem HTTP-Post alles geklappt zu haben).
Das Problem ist wahrscheinlich ein Rechteproblem; ich weiss nur nicht welches, da das Zielverzeichnis world-writable ist.Hast Du noch eine Idee?
BTW: $HTTP_*_VARS solltest Du nicht mehr benutzen und auch nicht register_globals = on, wenn es sich vermeiden lässt.
Wenn das die einzige Meldung ist, könnte das damit zusammenhängen, dass im Verzeichnis bereits ein File dieses Namens vorhanden ist, das schreibgeschützt ist. Das halte ich aber selber für unwahrscheinlich.
Für wahrscheinlicher halte ich, dass das eine verkürzte Fehlermeldung ist und Du bei
error_reporting(E_ALL);
ini_set('display_errors','On'); # oder '1'
ini_set('track_errors','On'); # oder '1'
und dann nach jeder IO-Operation die Variable $php_errormsg abfragen.
$fh = fopen($zieldatei,'w'); # $zieldatei kommt aus $_FILES['userfeldname']['tmp_name']
if (!empty($php_errormsg)) echo "htmlentities($php_errormsg)";
...
Probier es mal so, um die Ursach zu finden.
Später solltest Du dann move_uploaded_files() benutzen.
Harzliche Grüße aus http://www.annerschbarrich.de
Tom
Hi Tom,
Wenn das die einzige Meldung ist, könnte das damit zusammenhängen, dass im Verzeichnis bereits ein File dieses Namens vorhanden ist, das schreibgeschützt ist. Das halte ich aber selber für unwahrscheinlich.
genau; das Verzeichnis ist bislang (fast) leer; keine Uploads da, und auch keine Datei mit gleichem Dateinamen. Und es gehört apache und die Gruppe ist apache (mit diesem User/Gruppe wird auch die temporäre Datei auch in /tmp angelegt).
Für wahrscheinlicher halte ich, dass das eine verkürzte Fehlermeldung ist und Du bei
error_reporting(E_ALL);
ini_set('display_errors','On'); # oder '1'
ini_set('track_errors','On'); # oder '1'und dann nach jeder IO-Operation die Variable $php_errormsg abfragen.
Das hatte ich auch schon so in php.ini spezifiziert; aber trotzdem vielen Dank für den Tipp; dann muss ich demnächst zumindest nicht immer die globale php.ini ändern.
»»
$fh = fopen($zieldatei,'w'); # $zieldatei kommt aus $_FILES['userfeldname']['tmp_name']
if (!empty($php_errormsg)) echo "htmlentities($php_errormsg)";Probier es mal so, um die Ursach zu finden.
Da steht immer nur eine Sache:
Warning: copy(/var/www/html/db/script.sql): failed to open stream: Permission denied in /var/www/html/db/submit-exercise.php on line 118
(das ist ja sehr abstrakt) und:
htmlentities(failed to open stream: Permission denied)
Später solltest Du dann move_uploaded_files() benutzen.
Habe ich auch getestet... hier ist das (gleiche) Ergebnis:
Warning: move_uploaded_file(/var/www/html/db/script.sql): failed to open stream: Permission denied in /var/www/html/db/submit-exercise.php on line 119
Das Problem schein wirklich sehr tief irgendwo begraben zu sein; z.B. läuft das Script ohne Änderungen auf einer Sun mit einer anderen PHP-Version und einem anderen Rechte-System; habe schon alles verglichen, aber keinen Hinweis auf eine mögliche Fehlerquelle gesehen.
Trotzdem vielen Dank für Deine Antworten, Tom! Und wenn Dir noch was einfällt, dann wäre ich Dir auch sehr dankbar, wenn Du mich es wissen lassen könntest!
Hello,
if (!empty($php_errormsg)) echo "htmlentities($php_errormsg)";
das sollte so heißen:
if (!empty($php_errormsg)) echo htmlentities($php_errormsg);
Macht aber für die Fehlermeldung keinen Unterschied.
Da fällt mir aus dem Ärmel auch nix mehr ein.
Du kannst Nur den ganzen Pfad überprüfen mit fopen(). eben Verzeichnis-Stufe für Verzeichnis-Stufe.
Darfst Du denn wenigstens Irgendwohi kopieren?
Ich kenne die zusätzlichen Optionen Deiner Betriebssystemversion nicht. Es könnte ka auch sein, dass die Copy-Befehle für den User verboten sind. Was sagt denn die phpinfo() zu dem Thema 'verbotene Funktionen'?
Da müsste zwar eigentlich eine andere Fehlermeldung kommen, aber uneigentlich ist alles möglich.
Harzliche Grüße aus http://www.annerschbarrich.de
Tom