[2009–07–21] Nette\Caching\FileStorage ukládá do podadresářů

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
David Grudl
Nette Core | 8227
+
0
-

Kvůli nedokonalosti file systémů je potřeba počet souborů v jednom adresáři udržovat v rozumných mezích. Úložiště FileStorage ukládalo všechny soubory do jednoho adresáře (i když měly odlišný namespace). Což obecně není problém, protože lze v jednotlivých částech aplikace používat různé objekty FileStorage, každý nastavený na jiný adresář, nicméně pokud by i jednotlivé namespaces dělily prostor na další podadresáře, věci to může jen pomoci.

Dosud implementaci bránily mé obavy, že to bude způsobovat komplikace s přístupovými právy, nicméně nejlepší to bude asi vyzkoušet. Tudíž od revize 451 se soubory cache (a tedy i šablony) ukládají strukturovaně a dle výchozícho nastavení do složky cache v adresáři temp.

Pokud narazíte na nějaké komplikace, dejte mi vědět.

Patrik Votoček
Člen | 2221
+
0
-

Super… Ale je na to nějáké vypínátko? (Pro jistotu)

Petr Motejlek
Člen | 293
+
0
-

David Grudl napsal(a):

Kvůli nedokonalosti file systémů je potřeba počet souborů v jednom adresáři udržovat v rozumných mezích. Úložiště FileStorage ukládalo všechny soubory do jednoho adresáře (i když měly odlišný namespace). Což obecně není problém, protože lze v jednotlivých částech aplikace používat různé objekty FileStorage, každý nastavený na jiný adresář, nicméně pokud by i jednotlivé namespaces dělily prostor na další podadresáře, věci to může jen pomoci.

Dosud implementaci bránily mé obavy, že to bude způsobovat komplikace s přístupovými právy, nicméně nejlepší to bude asi vyzkoušet. Tudíž od revize 451 se soubory cache (a tedy i šablony) ukládají strukturovaně a dle výchozícho nastavení do složky cache v adresáři temp.

Pokud narazíte na nějaké komplikace, dejte mi vědět.

No super ;).

Jan Tvrdík
Nette guru | 2595
+
0
-

Zvážil bych, zda do Requirments checkeru nepřidat kontrolu na tvorbu nového adresáře a zápisu souboru do něj. Na hostingu se špatně nakonfigurovaným a zapnutým safe_modem to nebude fungovat.

David Grudl
Nette Core | 8227
+
0
-

Vypínátko ne – tím se nezjistí, jestli jsou podadresáře průchozí řešení. Vypínátko tedy až ve chvíli, kdy bude nutné.

ad requirements checker: jenže jak to udělat… checker by musel mít k dispozici adresář s povolením pro zápis.

Petr Motejlek
Člen | 293
+
0
-

David Grudl napsal(a):

Vypínátko ne – tím se nezjistí, jestli jsou podadresáře průchozí řešení. Vypínátko tedy až ve chvíli, kdy bude nutné.

ad requirements checker: jenže jak to udělat… checker by musel mít k dispozici adresář s povolením pro zápis.

Tak ono mít adresář, do kterého lze zapisovat, je de facto jeden z požadavků Nette ;). Bez tempu se nikam nehneš, takže to vlastně je jeden z požadavků. Pokud člověk není schopen zajistit, aby do adresáře, kam nahrál RequirementsChecker (nebo jakoukoliv cestu, kterou do něj dal), byl plný přístup, neměl by se pokoušet pouštět plnohodnotné Nette ;).

PetrP
Člen | 587
+
0
-

Takže mi to nefunguje ;/

Skončí to na tomhle returnu
adresare se vytvoří, mají oprávnění 0777

ale fopen($cacheFile, 'r+b') dopadne tímto fopen(): Unable to access /.../tmp/cache//c-Nette.Template/_4...0.%40layout.phtml.php

a fopen($cacheFile, 'wb') tímto fopen(): SAFE MODE Restriction in effect. The script whose uid is 3635 is not allowed to access /.../tmp/cache/c-Nette.Template owned by uid 48

Ve výsledku to ani nevyhodí chybu, málem jsem si nevšiml že to nefunguje.

Jak je vydět z chyby je zaplej safemode

David Grudl
Nette Core | 8227
+
0
-

m0t3jl napsal(a):

Tak ono mít adresář, do kterého lze zapisovat, je de facto jeden z požadavků Nette ;). Bez tempu se nikam nehneš, takže to vlastně je jeden z požadavků. Pokud člověk není schopen zajistit, aby do adresáře, kam nahrál RequirementsChecker (nebo jakoukoliv cestu, kterou do něj dal), byl plný přístup, neměl by se pokoušet pouštět plnohodnotné Nette ;).

Ale checker ten adresář nemá, nezná a třeba na webu ani neexistuje.

David Grudl
Nette Core | 8227
+
0
-

PetrP napsal(a):

Takže mi to nefunguje ;/

Jak je vydět z chyby je zaplej safemode

Jak se to dá řešit? Nemám se safemode zkušenosti.

David Grudl
Nette Core | 8227
+
0
-

Asi to řešit nepůjde – pod safe_mode se od rev. 452 použije starý režim.

PetrP
Člen | 587
+
0
-
// FileStorage::__construct()
$this->useSubdir = !ini_get('safe_mode') || !ini_get('safe_mode_gid');
// na
$this->useSubdir = !ini_get('safe_mode') && !ini_get('safe_mode_gid');

Jinak ta autodetekce nefunguje ;]

Jan Tvrdík
Nette guru | 2595
+
0
-

PetrP napsal(a):

// FileStorage::__construct()
$this->useSubdir = !ini_get('safe_mode') || !ini_get('safe_mode_gid');
// na
$this->useSubdir = !ini_get('safe_mode') && !ini_get('safe_mode_gid');

Jinak ta autodetekce nefunguje ;]

Mě vyhovuje současný stav, protože u Armina běží správně nastavený safe_mod, takže mi ukládání do podadresářů bez problému funguje a díky tomu || !ini_get('safe_mode_gid'); se mi zapne.

David Grudl
Nette Core | 8227
+
0
-

!ini_get('safe_mode') || !ini_get('safe_mode_gid'); = pokud je safe_mode a zároveň safe_mode_gid, adresáře se nepoužijí.

PetrP
Člen | 587
+
0
-

V tom případě je chyba jinde:

d(
	ini_get('safe_mode'),
	ini_get('safe_mode_gid'),
	!ini_get('safe_mode') || !ini_get('safe_mode_gid')
);
array(3) {
   0 => string(1) "1"
   1 => string(0) ""
   2 => bool(TRUE)
}

useSubdir se zapne, ale ukládání do vytvořených adresářú nefunguje. Znaméná to tedy že je asi špatně nastavenej server, to nic nemění na faktu že by to i tak mělo fungovat.

Takže existuje nějaké lepší řešení detekce? co mám dumpnout?

romansklenar
Člen | 655
+
0
-

Vyřešil jsi to nějak Petře? Řešíme teďkom stejný problém – server (banán) je nastaven stejně jako u tebe (podle dumpu)

safe_mode = On
safe_mode_gid = Off

Jestli je server špatně nastaven, to netuším, ale někde jsem se dočet, že pokud je safe_mode_gid zaplý tak aby fungoval přístup do souborů, musel by mít na serveru každý uživatel svou skupinu. O tom jak to mají hostéři vím prd, ale tipl bych, že na sdílených hostinzích toto nemusí být dodržováno.

Editoval romansklenar (28. 7. 2009 15:43)

PetrP
Člen | 587
+
0
-

Nevyřešil. Tady hodil jsem si tam $this->useSubdir = false; a čekam až se david vrátí.

Řešení typu dát useSubdir jako public se mi nelíbí protože Caching by měl fungovat rovnou bez nějakého magického nastavovaní.

Na tomto řádku to spadně když je useSubdir na true a nejde do adresaru zapisovat.
Takže tam v tuhle chvíly skusit znova uložit z useSubdir false s tim si to někam uložit a příště to zahrnout do autodetekce a subdir nepovolit.

Petr Motejlek
Člen | 293
+
0
-

David Grudl napsal(a):

m0t3jl napsal(a):

Tak ono mít adresář, do kterého lze zapisovat, je de facto jeden z požadavků Nette ;). Bez tempu se nikam nehneš, takže to vlastně je jeden z požadavků. Pokud člověk není schopen zajistit, aby do adresáře, kam nahrál RequirementsChecker (nebo jakoukoliv cestu, kterou do něj dal), byl plný přístup, neměl by se pokoušet pouštět plnohodnotné Nette ;).

Ale checker ten adresář nemá, nezná a třeba na webu ani neexistuje.

Já měl právě na mysli, že by se do toho muselo šáhnout a muselo se mu říct, kde ho má hledat – prostě otevřít ten php soubor a někde na prvním řádku nastavit hodnotu proměnné.

Cifro
Člen | 245
+
0
-

Potvrdzujem, ten istý dump a to isté chovanie ako Roman a PetrP na hostingu freeserver.sk

Edit: a ani sa to neprepne do stareho režimu :(

Editoval Cifro (31. 7. 2009 23:35)

David Grudl
Nette Core | 8227
+
0
-

Tedy adresář se vytvoří ale nelze do něj zapisovat, je to tak?

Možná to není kvůli safe mode – můžeš zkusit celý temp včetně podadresářů smazat a doplnit za mkdir (cca sem) chmod($dir, 0777), jestli to pomůže?

Jinak by asi nezbývalo než tvorbu adresářů zakázat pro safe mode paušálně.

Jan Tvrdík
Nette guru | 2595
+
0
-

David Grudl napsal(a):

Jinak by asi nezbývalo než tvorbu adresářů zakázat pro safe mode paušálně.

Určitě bych nechal i možnost to nastavit ručně, protože přestože zapnutý safe_mode na většině hostingů způsobí nemožnost zápisu do složek, které si PHP vytvořilo, tak existují i hostingy, na kterých to i se zapnutým safe_modem funguje.

romansklenar
Člen | 655
+
0
-

U mě nepomohlo.

SAFE MODE Restriction in effect. The script whose uid is 100116 is not allowed to access /srv4/.../app/temp/cache/c-Nette.RobotLoader owned by uid 33.

When safe mode is enabled, PHP checks whether the files or directories you are about to operate on have the same UID (owner) as the script that is being executed. In addition, you cannot set the SUID, SGID and sticky bits.

chown tady taky nepomůže – ta samá omezení.

Editoval romansklenar (3. 8. 2009 15:49)

Cifro
Člen | 245
+
0
-

Myslím že to nepomôže. Ako to funguje vysvetľuju admini mojho hostingu na fóre:

http://forum.freeserver.sk/viewtopic.php?…

Citujem jeden príspevok:

ked v nejakom skripte zavolas mkdir(‚mojadresar‘,777) adresar sa vytvori, ale jeho owner(vlastnik) je apache. Vlastnostou safemodu je, ze PHP vzdy predtym, ako siahne na nieco vo filesysteme tak zisti, ci vlastnikom toho adresara(suboru) si ty.

Adresare a subory čo kopirujem maju vlastnika takeho akym som prihlaseny na ftp. Ale subory a adresare čo vytvara php majú vlastnika iného i keď majú práva nastavené také ako sa zadali napr. v mkdir na 777, mne konkretne ukazuje FileZilla že vlastnik adresára a súborov vytvaranych php je „(?)“, asi to nevie FileZilla zistiť preto ten otaznik.

Ani to chmod($dir, 0777) nepomáha. A prečo to nepomáha je v tom citovanom prispevku. Skúšal som aj chown($dir, "username") ale tiež bez šance.

Jinak by asi nezbývalo než tvorbu adresářů zakázat pro safe mode paušálně.

Takže asi to bude musieť byť takto. Alebo pomocou FTP funkcii vytvarať adresáre, ale to by už sa muselo zadať napr. do config.ini aj meno a heslo na ftp :/

David Grudl
Nette Core | 8227
+
0
-

Ten test by se musel rozšířit tak, že v případě safe mode nejprve zjistí, zda tempdir spadá do safe_mode_include_dir a pokud ne, tak vytvoří adresář a zjistí, jestli se vytvořil se stejným UID (nebo GID když je povolen safe_mode_gid) je stejný jako UID/GID volaného skriptu (tuším $_SERVER['SCRIPT_FILENAME']).

Což je docela komplikované, takže by se to mohlo zjednodušit: při safe mode prostě zkusit do adresáře zapsat soubor. Pokud se to nepovede, vypne používání adresářů.

Patrik Votoček
Člen | 2221
+
0
-

napadá mě ještě zkusit přidat ini_sety na safe_mode_exec_dir a safe_mode_include_dir a zkusit ručně přidat temp složku jestli to nepomůže. (Nevím jestli se tohle dá vůbec pomocí ini_set nastavovat a taky záleží jestli je ini_set vůbec dostupné)

Edit: sám s tím problém nemám (hostuju u sebe na serveru) a nechce se mě rozcházet testovací prostředí se save_mode. Takže to někdo otestujte.

Editoval vrtak-cz (3. 8. 2009 17:35)

David Grudl
Nette Core | 8227
+
0
-

safe mode nelze přes ini_set měnit.

PetrP
Člen | 587
+
0
-

David Grudl napsal(a):

Tedy adresář se vytvoří ale nelze do něj zapisovat, je to tak?

Možná to není kvůli safe mode – můžeš zkusit celý temp včetně podadresářů smazat a doplnit za mkdir (cca sem) chmod($dir, 0777), jestli to pomůže?

Jinak by asi nezbývalo než tvorbu adresářů zakázat pro safe mode paušálně.

Potvrzuju co psaly i ostatní chmod($dir, 0777) nic nezměnil.

Jinak adresáře se vytvářejí, podle ftp mají oprávněni 0777 (už od mkdir) ale zapisovaní se nekoná.

Asi globálně bych to pro savemode nevypínal ale udělal ten test z vytvořením souboru (samozřejmě jen jednou). Tedy jestli se to nedá jinak detekovat. možná by mohl Jan Tvrdík poslat phpinfo serveru (jestli mu to funguje z savemodem) že by jsme ho porovnali z našim.

Jan Tvrdík
Nette guru | 2595
+
0
-

PetrP napsal(a):

Možná by mohl Jan Tvrdík poslat phpinfo serveru (jestli mu to funguje z savemodem) že by jsme ho porovnali z našim.

safe_mode On
safe_mode_exec_dir no value
safe_mode_gid Off
safe_mode_include_dir no value

Celé phpinfo

Cifro
Člen | 245
+
0
-

Všetko z mojho phpinfo kde bolo safe_mode:

Directive Local Value Master Value
safe_mode On Off
safe_mode_exec_dir /home/safemode /home/safemode
safe_mode_gid Off Off
safe_mode_include_dir ./:/home/data/pear/:/home/server/webpanel/:/usr/local/lib/php/pear/ ./:/home/data/pear/:/home/server/webpanel/:/usr/local/lib/php/pear/
safe_mode_allowed_env_vars PHP_,LC_LANG,LANGUAGE,TZ,LANG PHP_,LC_LANG,LANGUAGE,TZ,LANG
safe_mode_protected_env_vars LD_LIBRARY_PATH LD_LIBRARY_PATH
PetrP
Člen | 587
+
0
-
"safe_mode" => string(1) "1",
"safe_mode_allowed_env_vars" => string(4) "PHP_",
"safe_mode_exec_dir" => string(12) "/phpallowfc/",
"safe_mode_gid" => string(0) "",
"safe_mode_include_dir" => string(30) "/phpallowdir/:/usr/share/pear5",
"safe_mode_protected_env_vars" => string(15) "LD_LIBRARY_PATH",
Inza
Člen | 330
+
0
-

Mám rád podadresáře;-) – konečně lze promazat rozumně jen část keše… (ručně během vývoje) Supr!

Jan Tvrdík
Nette guru | 2595
+
0
-

Existuje nějaký důvod k použití toho prefixu c-? Nestačí, že je to celé obalenou složkou cache?

David Grudl
Nette Core | 8227
+
0
-

Tak už by tam mělo být funkční ověřování pro safe mode.