Autor Zpráva
Nich
Profil
Mám problém s uploadem souboru... nevyplivne to ani žádnou chybovou hlášku, jen podle echa "Possible file upload attack!" vždycky zjistím, že se upload nezdařil a soubor se na FTP nedostal... nevíte někdo prosím kde může být chyba?

//Pripojeni k FTP
$ftp_server = "ftp.ftp.cz";
$ftp_user = "login";
$ftp_pass = "heslo";

// set up a connection or die
$conn_id = ftp_connect($ftp_server) or die("Couldn't connect to $ftp_server"); 

// try to login
if (@ftp_login($conn_id, $ftp_user, $ftp_pass)) {
    echo "Connected as $ftp_user@$ftp_server\n";
} else {
    echo "Couldn't connect as $ftp_user\n";
}

// upload a file
$uploaddir = '/home/uzivatele/brodek/http/images/icons/';
$uploadfile = $uploaddir . basename($_FILES['name']['tmp_name']);
if (move_uploaded_file($_FILES['name']['tmp_name'], $uploadfile)) {
echo "File is valid, and was successfully uploaded.\n";
} else {
echo "Possible file upload attack!\n";
}

// close the connection
ftp_close($conn_id); 
Taps
Profil
Nich:
nemáš chybně zapsanou cestu $uploaddir ?
Nich
Profil
Taps:
Cesta by měla být v pořádku

var_dump(is_dir('/home/uzivatele/brodek/http/images/icons/'));


Vrátilo mi to bool(true) takže složka existuje tudíž cesta k ní musí být taky správná
Taps
Profil
Nich:
myslím si že do upload cesty by jsi měl zadát adresář který si vytvoříš na ftp. zkus to a uvidíš
Nich
Profil
Taps:
Já tu složku mám už dávno vytvořenou (; ... ale ten soubor tam prostě nemůžu nacpat :-(
Jan Tvrdík
Profil
Nich:
Zkus si dumpnout is_writable($uploaddir) nebo ještě lépe zapnout vypisování chyb.

EDIT: Ještě jinak – ty se pokoušíš nahrát ten soubor na FTP? Jestli ano, tak samozřejmě nebude fce move_uploaded_file fungovat. Je potřeba použít ftp funkce.
AM_
Profil
máš tam nějaké divné indexování $_FILES. Opravdu je jméno pole pro soubor ve formuláři "name", tedy <input type="file" name="name">? Mělo by to být spíš takto:
<input type="file" name="soubor">
....
<?php
$uploadfile = $uploaddir . $_FILES['soubor']['name'];
if (move_uploaded_file($_FILES['soubor']['tmp_name'], $uploadfile))
?>

Jinak jak píše Jan Tvrdík, na FTP ten soubor takhle nedostaneš, k tomu musíš použít FTP funkce, ale alespoň budeš vědět, že k tomu poli FILES přistupuješ špatně.
fopen
Profil *
Pomôžem trochu
if (move_uploaded_file($_FILES['name']['tmp_name'], $uploadfile)) {
	echo "File is valid, and was successfully uploaded.\n";
	$name = $_FILES['name']['name'];
	//Transfer mode must be either FTP_ASCII or FTP_BINARY. 
	if (ftp_put($conn_id, $name, $uploadfile, 'FTP_BINARY')) { 
		echo 'File "'.$name.'" successfully transfered.';
		if(@unlink($uploadfile)){
			echo'Clear FTP temp dir.';
		}
	} else {
		echo'FTP Transfer failed.';
	}
} else {
	echo "Possible file upload attack!\n";
}

Kde premenná $uploadfile musí obsahovať adresárovu cestu aj z názvom (v našom prípade dočasného) súboru, pričom adresár musí mať povolený zápis pre všetky kategórie užívaťeľov, tzv. chmod 777.
Nich
Profil
Všem děkuji za rady...

fopen:
//Tady máš chybu, nemá to být string, takže bez apostrofů
if (ftp_put($conn_id, $name, $uploadfile, 'FTP_BINARY')) {


To je ale jedno... Pomocí vašich postů sem teda něco splácal :D, doufám, že k dokonalosti a funkčnosti mě dělí jen vláseček

$uploaddir = "/http/images/icons/";
$uploadfile = $uploaddir . $_FILES['nov_file']['name'];
    chmod($uploadfile, 7777);
    $name = $_FILES['nov_file']['name'];
	//Transfer mode must be either FTP_ASCII or FTP_BINARY. 
    if (ftp_put($conn_id, $name, $uploadfile, FTP_BINARY)) {
 echo "successfully uploaded $file\n";
} else {
 echo "There was a problem while uploading $file\n";
}


Bohužel to na stránce vyhazuje pár chyb (asi bude nějakej problém s tou funkcí chmod()):


Warning: chmod() [function.chmod]: open_basedir restriction in effect. File(/http/images/icons/aaaaaaaa.JPG) is not within the allowed path(s): (/tmp:/var/tmp:/etc/phpmyadmin/:.:/home/uzivatele/brodek/http) in /home/uzivatele/brodek/http/index.php on line 157

string(12) "aaaaaaaa.JPG"
Warning: ftp_put() [function.ftp-put]: open_basedir restriction in effect. File(/http/images/icons/aaaaaaaa.JPG) is not within the allowed path(s): (/tmp:/var/tmp:/etc/phpmyadmin/:.:/home/uzivatele/brodek/http) in /home/uzivatele/brodek/http/index.php on line 161

Warning: ftp_put(/http/images/icons/aaaaaaaa.JPG) [function.ftp-put]: failed to open stream: Operace není povolena in /home/uzivatele/brodek/http/index.php on line 161
Jan Tvrdík
Profil
Nich:
Změn si $uploaddir = "/http/images/icons/"; na "/home/uzivatele/brodek/http/images/icons/"
Nich
Profil
Jan Tvrdík:
To když udělám tak se stane tohle:



Warning: chmod() [function.chmod]: není souborem ani adresářem in /home/uzivatele/brodek/http/index.php on line 157

Warning: ftp_put(/home/uzivatele/brodek/http/images/icons/aaaaaaaa.JPG) [function.ftp-put]: failed to open stream: není souborem ani adresářem in /home/uzivatele/brodek/http/index.php on line 160
There was a problem while uploading



S tou cestou je to stejně ňáky celý zajímavý. Když se lognu na FTP třeba přes commandera tak se objevím jakody ve složce /brodek/. Tzn. že cesta kam to chci uložit by byla /http/images/icons/. Před http složka brodek už nebude, protože v té jsem jakokdyby loglej (root)

Takže teď nevím kterou cestu mám použít :-). Je ale dobrý, že ani jedna nefunguje xD.
fopen
Profil *
Nich máš pravdu, nie je to reťazec, moja chyba.

Mam zato že tu existuje konflikt medzi "http" protokolom na ktorom beží samotný skript a "ftp" protokolom.
V ideálnom prípade by to malo fungovať takto:
ftp_put($FTPStream, $_FILES[$FTPFile]['name'], $_FILES[$FTPFile]['tmp_name'], FTP_BINARY);

Lenže z nejakych dôvodov funkcia ftp_put() nemá na väčšine serverov prístup do "tmp" adresára určného na upload súborov cez html formular a to je ten problem, pričom funkcie is_uploaded_file() a move_uploaded_file() áno. Preto je potrebne pomocou move_uploaded_file() presunúť súbor do alternatívneho dočasného adresára, ktorý ma nastavený chmod na 0777 najlepšie pomocou regulerneho ftp klienta.
Nich
Profil
fopen:
Ale šak do funkce ftp_put už vcházijou jen čisty PHP proměnný...

ftp_put($conn_id, $name, $uploadfile, FTP_BINARY) {}


EDIT:
A když si tyhle dvě proměnný ($name, $uploadfile) dumpnu tak to už sou prostě jen stringy , tam by žádnej konflikt nastat neměl :-)
EDIT_2:
Aha špatně sem tě pochopil... už vím jak to myslíš
fopen
Profil *
Nich:
ak chceš môžem ti tu postnuť na naštudovanie celu metodu AddFile() ktorú som napisal do svojho PHPFTPKlienta, laboroval som na nej par dni, zistil som že to ma nejaké obmedzenia, ale nakoniec to funguje.
Nich
Profil
fopen:
Každá pomoc dobrá... prcni to sem :-)
fopen
Profil *
Ale je v surovom stave vyiňata z triedy
	public function AddFile() {
		
		if($_FILES[$this->FTPFile]['error'] == 0){
			
			if($_FILES[$this->FTPFile]['size'] < $this->UploadMaxFilesize){
				
				$this->PrintVar['FTPFile'] = $_FILES[$this->FTPFile];

				switch($_POST['transfer_mode']){
					case'FTP_ASCII':
						$transfer_mode=FTP_ASCII;
						$this->Msg[] ='Transfer mode "FTP_ASCII".';
					break;
					case'FTP_BINARY':
					default:
						$transfer_mode=FTP_BINARY;
						$this->Msg[] ='Transfer mode "FTP_BINARY".';
					break;
				}

				$tmp_name = $_FILES[$this->FTPFile]['tmp_name'];

				$name = $_FILES[$this->FTPFile]['name'];
				
				$tempname = $this->FTPTemp.md5($name);

				//if (ftp_nb_put($this->FTPStream, $name, $tmp_name, $transfer_mode)) {
				/*
					if ( $fp = @fopen($tempname, "rb")) {
						$this->Msg[] = 'File pointer ready.';
						if (@ftp_fput($this->FTPStream, $name, $fp, $transfer_mode)) {
							$this->Msg[] = 'File "'.$name.'" successfully atransfered.';
						}
					}else{
						$this->Msg[] = 'File pointer failed.';
					}
				*/
				if (@ftp_put($this->FTPStream, $name, $tmp_name, $transfer_mode)) { 
					$this->Msg[] = 'File: "'.$name.'" successfully transfered.';
				}else{
					$this->Msg[] = 'File: "'.$name.'" ftp transfer failed. Continue to alternate upload method.';
					if(@is_uploaded_file($tmp_name)){
						$this->Msg[] = 'File "'.$name.'" successfully uploaded.';
						
						if(@move_uploaded_file( $tmp_name, $tempname )){
							$this->Msg[] = 'File "'.$name.'" successfully moved to FTP temp dir.';
	
							if (ftp_put($this->FTPStream, $name, $tempname, $transfer_mode)) { 
								$this->Msg[] = 'File "'.$name.'" successfully transfered.';
								if(@unlink($tempname)){
									$this->Msg[] = 'Clear FTP temp dir.';
								}
								
							} else {
								$this->Msg[] = 'FTP Transfer failed.';
							}
						}else{
							$this->Msg[] = 'File: "'.$name.'" not moved, insufficient privileges?';
						}
					}else{
						$this->Msg[] = 'File: "'.$name.'" not uploaded.';
					}
				}
				
			}else{
				$this->Msg[] = 'File is over than "'.Common::HumanFileSize($this->UploadMaxFilesize).'" - exactly: '.Common::HumanFileSize($_FILES[$this->FTPFile]['size']).'.';
			}
		}else{
			$this->Msg[] = 'File transfer error "'.$_FILES[$this->FTPFile]['error'].'".';
		}
	}
Nich
Profil
fopen:
Už sem si ten tvůj scriptik upravil... kdyžtak ho sem za chvilu vložim..., ale zjistil sem docela zajímavou věc, když dumpnu $_FILES tak dostanu tohle:

array(1) { ["nov_file"]=>  array(5) { ["name"]=>  string(12) "aaaaaaaa.JPG" ["type"]=>  string(0) "" ["tmp_name"]=>  string(0) "" ["error"]=>  int(1) ["size"]=>  int(0) } }


A pokud mě zrak neklame tak $_FILES['tmp_name'] je prázdná!!
fopen
Profil *
ak ['error'] = 1
UPLOAD_ERR_INI_SIZE
Value: 1; The uploaded file exceeds the upload_max_filesize directive in php.ini.

v tomto pripade bude ['tmp_name'] prazdna...

viac tu: Error Messages Explained
Nich
Profil
brodek.skauting.cz/phpinfo.php

Tady je odkaz, jak to mám nastaveny... je tam limit 2MB... ale když uploaduju menší soubor tak to stejně nefunguje myslím, že je nějak špatně nastavená ta cesta... nevykoumá někdo z toho phpinfa jaká je domovská složka po připojení k FTP?
Nich
Profil
Tady je ten script... sice to napíše "File: filik.jpg successfully transfered." Ale na FTP je prd

                $tmp_name = $_FILES['nov_file']['tmp_name'];
				
                $name = $_FILES['nov_file']['name'];
                
                $tempname = "/home/uzivatele/brodek/http/images/icons/" . basename($name);	
				
				$transfer_mod = FTP_BINARY;
				
                if (ftp_put($conn_id, $name, $tmp_name, $transfer_mode)) { 
                   echo "File: ".$name." successfully transfered.";
                }else{
                    echo "File: ".$name." ftp transfer failed. Continue to alternate upload method.";
                    if(is_uploaded_file($tmp_name)){
                        echo "File".$name."successfully uploaded.";
                        
                        if(move_uploaded_file( $tmp_name, $tempname )){
                            echo "File ".$name." successfully moved to FTP temp dir.";
    
                            if (ftp_put($conn_id, $name, $tempname, $transfer_mode)) { 
                                echo"File ".$name." successfully transfered.";
                                if(unlink($tempname)){
                                    echo "Clear FTP temp dir.";
                                }
                                
                            } else {
                                echo "FTP Transfer failed.";
                            }
                        }else{
                            echo "File: ".$name." not moved, insufficient privileges?";
                        }
                    }else{
                        echo "File: ".$name." not uploaded.";
                    }
                }
fopen
Profil *
ak ti skript beží v adresari "/home/uzivatele/brodek/http/" skus použit pre "$tempname" relativnu cestu "/images/icons/".$name;
inak uz neviem
AM_
Profil
fopen:
relativnu cestu "/images/icons/".$name;
/cokoliv není relativní cesta, relativně by to bylo "images/icons/".$name; / na začátku značí cestu absolutní.
Nich
Profil
                $tmp_name = $_FILES['nov_file']['tmp_name'];
                
                $name = $_FILES['nov_file']['name'];
                
                $tempname = "images/icons/" . $name;    
                
                $transfer_mod = FTP_BINARY;
                
                if (ftp_put($conn_id, $name, $tmp_name, $transfer_mode)) { 
                   echo "File: ".$name." successfully transfered.";
                }else{ echo "File: ".$name." not uploaded."; }


Tady v tomhle případě už se soubor konečně na FTP dostane (přesněji sem "/home/uzivatele/brodek/uploaded_file.jpg"), ale když chci, aby se soubor dostal až sem ("/home/uzivatele/brodek/http/images/icons/") tak to za boha nemůžu udělat :-).



Zkusil sem to udělat přes tu relativní cestu jak píšete (přesněji "images/icons/" . $name), jen sem v tom scriptu (viz. výše (tento příspěvek)) upravil funkci ftp_put() na

ftp_put($conn_id, $name, $tempname, $transfer_mode);


Bohužel se v tomhle případě soubor nedostal nikam :-). Tady je bug report:

Warning: ftp_put(images/icons/filik.jpg) [function.ftp-put]: failed to open stream: není souborem ani adresářem in /home/uzivatele/brodek/http/index.php on line 166
AM_
Profil
no tak to asi nepůjde jednou funkcí rozkopírovat na dvě místa, natož když jedno je na FTP a jedno na lokálním disku...
$tmp_name = $_FILES['nov_file']['tmp_name'];
$name = $_FILES['nov_file']['name'];
$transfer_mode = FTP_BINARY;
       
if (move_uploaded_file($tmp_name, "images/icons/" . $name)) { 
                   echo "File: ".$name." successfully moved.";
                }else{ echo "File: ".$name." not uploaded."; }                
if (ftp_put($conn_id, $name, "images/icons/" . $name, $transfer_mode)) { 
                   echo "File: ".$name." successfully transfered.";
                }else{ echo "File: ".$name." not uploaded."; }

                

Snad to mám dobře, princip je dočasný soubor nejdřív přemístit na trvalé umístění (images/icons) a pak ODSUD uploadovat.
Nehledat v tom žádnou vědu, není to nic složitého, jen si uvědomit, v jakou chvíli existuje jaký soubor na jakém místě, metodou pokusu a omylu s dosazováním proměnných se nikam nedobéřeš :)
Nich
Profil
AM:
No tak už do toho začínám pronikat xD, ale bohužel tvůj script vyhodil

Warning: move_uploaded_file(images/icons/filik.jpg) [function.move-uploaded-file]: failed to open stream: Přístup odmítnut in /home/uzivatele/brodek/http/index.php on line 162

Warning: move_uploaded_file() [function.move-uploaded-file]: Unable to move '/tmp/phpcz8zq5' to 'images/icons/filik.jpg' in /home/uzivatele/brodek/http/index.php on line 162

File: filik.jpg not uploaded.

Warning: ftp_put(images/icons/filik.jpg) [function.ftp-put]: failed to open stream: není souborem ani adresářem in /home/uzivatele/brodek/http/index.php on line 165

File: filik.jpg not uploaded.


Asi to odmítá ten přístup kvůli právům ne?

Btw. trochu jsem koukal do toho phpinfo() a objevil jsem upload_tmp_dir = no value nemůže to nějak blbnout kvůli tomu?
AM_
Profil
ano, je to kvůli právům, images/icons nastav na 777.
výchozí upload_tmp_dir je /tmp, což evidentně funguje.
Nich
Profil
if(chmod("images/icons/", 777)) {
		 echo "Práva byla nastavena";
		 } else {
		 echo "Práva nebyla nastavena";	 
		 }


Error report:

Warning: chmod() [function.chmod]: Operace není povolena in /home/uzivatele/brodek/http/index.php on line 163
Práva nebyla nastavena
fopen
Profil *
ked uz, tak:
ftp_chmod($conn_id, 0777, "images/icons/" );

jednoduchy chmod() sa dá použivať iba v adresároch ktoré už majú prednastavený chmod na 0774, 0776 alebo 0777
Nich
Profil
fopen:
ani ftp_chmod() nepomohl :´-(

Warning: ftp_chmod() [function.ftp-chmod]: Could not change perms on images/icons/: No such file or directory in /home/uzivatele/brodek/http/index.php on line 163
Pelpet
Profil *
Nevím jak to máš dělané, ale jestli děláš soubor pomocí "fopen();" tak ti to nepůjde.
Nejsi totiž vlastník (owner). Vlastník je obyčejně nějaké dlouhé číslo, nebo "www-data".
Proto ti ftp_chmod nepomůže, protože pomocí funkcí ftp_ něco můžeš pracovat jen s vlastníma věcma.
takže to musíš udělat takhle:

<?php
$f=fopen("soubor...","w"); //soubor musí být STRING!! musí to být forma $dirname.$filename
chmod("soubor...",0777);
fclose($f);
?>

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm:

0