Jak funguje mkdir / chmod v PHP
Řešil jsem dnes problém na ŠTĚRBA-KOLA.cz, kdy klient mohl nahrát soubory na web pomocí WYSIWYG editoru / PHP, nicméně dále je nemohl smazat přes FTP. Nechápal jsem proč, adresáře se vytvářejí pomocí mkdir($dir,0777)
, na soubory se nastavuje chmod($fp,0777)
, a žádná jiná prezentace s tím neměla dosud problém.
Vyřešilo se to až ve spolupráci s webhostingem (tojeono.cz). Problém je, že mkdir 0777
ve skutečnosti nedělá v PHP mkdir 0777
. Bere totiž do úvahy i systémovou masku, která je typicky nastavená pro *nixové uživatele na 0022, takže udělá pouhé 0755. A v php.ini ani v httpd.conf se to bohužel nedá změnit. Pokud tuto triviální informaci víte, vše je jasné, já jsem ji do dnešního dne nevěděl. Je tedy nutné před mkdir()
použít ještě umask(0000)
, tedy vynulovat masku, a vše bude fungovat dle očekávání.
Druhou možností je samozřejmě nastavit defaultní umask v *nixovém systému na 0000. Poté i PHP bude fungovat tak, jak očekáváte, a nebude problém v syncu práv mezi PHP a FTP. Je to nakonec nejlepší řešení, protože spousta skriptů umask nepoužívá, a dopisovat to do skriptů je poněkud méně pohodlné. Navíc umask funguje jen pro nejbližší další příkaz, poté se opět resetuje do původního stavu, takže se nedá vložit jen do nějakého config.php.
Bezvadné by bylo, kdyby PHP podporovalo v php.ini cosi jako set_default_umask, pár requestů na to již (pár let) je.
S tímhle (0755) jsem se párkrát setkal, a neznaje fígl s umask() jsem se PHPčkem připojoval přes FTP a takto vytvářel adresáře a nahrával soubory. Děkuji za radu ;-)
[1] njn, ona je to úplně triviální věc, nicméně, těch trivialit je tolik, že není problém jednu minout..
Sláva, konečně už nebudu muset otravovat podporu, ať mi vytvoří adresář s chmodem 777. Kolikrát jsem málem hodil monitor z okna, když se opět objevila hláška "cannot access /adresar in xy.php on line 5" nebo jak ta hláška vypadá.
Vypadá to, že podpora tojeono.cz má kvalitu :o).
Tohle jsme taky nějaký čas zpátky řešil, ale stačilo se podívat do manuálu PHP a projít komentáře k mkdir, tam to je. Manuál je občas k nezaplacení, obzvlášť vzhledem k tomu kolik má PHP funkcí.
[5] No jak to vezmeš - většina hostingů ma omezenou velikost databáze. Ukládat proto do ní soubory v binární podobě není nejschůdnější cestou.
Jde pomocí copy kopírovat soubory do vzdálených adresářů jiných webu nebo ne?
[6] Taky by mě zajímalo, jakou neplechu může 0777 na souborech/složkách způsobit.
[7] Tak jsem si četl manuál a funkce copy neumí kopírovat přes http protokol. Myslím si, že práva 777 jsou adresáři bezpečná (některé servery mají nastavení tak, že 777 vypisuje zároveň obsah adresáře - to lze vyřešit umístěním indexu nebo zakázat indexes v .htaccess) a nevidím důvod nahrávat data do databáze. Dovolil bych si i tvrdit že data tahaná z MySQL binární podobou je pro webovou aplikaci opravdu blbost - musíte si nejdřív soubor binárně otevřít, pak uložit, pak stáhnout a poslat skriptu správnou hlavičku aby to jen nevypsalo sta řádků nesmyslů.
A není tento problém uměle vyvolán špatnou konfigurací providera? Přeci každý FTP server při přihlášení přidělí uživateli práva. Proč prostě nemůže přidělit uživatele, pod kterým přistupuje PHP?
[9] provozovat FTP pod stejným uživatelem v Linuxu jako PHP je bezpečnostní sebevražda..
[9] Třeba kvůli tomu, že potom ztrácí smysl safe_mode, na kterém je bezpečnost většiny obyčejných hostingů postavena? :-)
Ale hlavně ať si to nepřečte nějaký "taky administrátor" a nenastaví umask na 0000 pro všechny včetně roota.
Včera jsem řešil to samé, ale ani umask() nepomáhal, práva se podařilo nastavit jedině a pouze přes k tomu oprávněného ftp uživatele. Pokud by ani tohle nevyšlo, tak když by php bylo zkompilováno/instalováno s podporou ftp, šel by určitě kód přepsat používajíc ftp rozšíření k práci se soubory.
... kdy klient mohl nahrát soubory na web pomocí WYSIWYG editoru / PHP, nicméně dále je nemohl smazat přes FTP. ...
Nějak mi uniká jak jsi vlastně zabránil tomu smazaní přes ftp.
Jinak prosím omluv mé, určitě v poměru s tvým, nízké IQ, snad se ti mě zželí a relavantně odpovíš, protože já jsem se toho z článku nedovtípil a to jsem ho zpracovával cyklem while(1) než jsem přestal samým vyčerpáním. I když možná tuším, že tvé php nastavuje něco jako php user group, ke kterým pak nemá přístup určitá skupina uživatelů ftp. Opravdu nevím, děkuji převelice za případné vysvětlení. Omlouvám se také za případné stylistické a pravopisné chyby příspěvku, ale četl jsem to po sobě 5x, tak doufám, že to zas až taková hrůza nebude.
No jak se to vezme. Zalezi na hostingu kde si a jak ma v php nastavbnou promenou OPEN_BASEDIR(zjistis pomoci php info) Na jednom malem hostingu jsem zjistil ze to tam tak maji a pak si jednoduchym scriptem kdokoliv od tebe stahne celej web i se zdrojakama. Ale rekl sem jim o tom a oni to uz odstranili. Kolik dalsich hostingu je deravych, tak to tezko rict.
[12] Řekl bych, že došlo k nedorozumění - citovaná věta nepopisovala zadání, ale nežádoucí stav. Je fakt, že slovo "problém" se často používá pro obojí.
Cílem bylo, aby to šlo mazat přes FTP, jenže to nešlo, protože PHP nevytvořilo anarchistický soubor (kdokoli smí cokoli), ale soubor s právy rwxr-xr-x.
to je ale priklad pomerne laxne napsane aplikace, resp ne-snaha nakonfigurovat to spravne a "pohrat si s tim" ... pristupova prava jsou tam proto, aby se pouzivala .. tzn, veskera webova prezentace ma mit prava 700 resp 600 pouze pro uzivatele pod kterym bezi HTTP daemon, nikdo jiny k nim nema mit pristup .. pokud je potreba, aby uzivatele neco na server uploadovali nebo mazali jinak pres HTTP daemon, je potreba prislusne nakonfigurovat pro ty ktere adresare ty sluzby a skupiny ktere s nimi maji pracovat, tedy v nejhorsim 770/660 ... nastavit na cely web vcetne uploadnutych souboru 777 je proste absolutni zhuverilost
Možno som trochu mimo, ale ja som zatial používal unlink () na mazanie suborov. Na dvoch rôznych hostingoch a zatiaľ nebol problém.
[12] Všimni si v té větě rozdílu mezi slůvkem, kdyby bylo slůvko kdy nahrazeno za aby.
[18] Právě naopak, ty nuly tam jsou zcela správně, naopak bez nich by to bylo špatně, viz. manuál PHP - "To ensure the expected operation, you need to prefix mode with a zero (0):
<?php
chmod("/somedir/somefile", 755); // decimal; probably incorrect
chmod("/somedir/somefile", "u+rwx,go+rx"); // string; incorrect
chmod("/somedir/somefile", 0755); // octal; correct value of mode
?> "
[18] Nejdřív bych si zjistil jaký je rozdíl mezi maskou (umask) a právy (chmod). Jsou to dvě prakticky opačné věci.
PHP má snad nejlepší manuály vůbec.
Bohužel zásoba nepříjemných "překvapení" je velká a kdo tvrdí, že ještě nikdy nenarazil na nějaký problém tak ten to dělá dodnes.
[14] [17] Už mi to docvaklo, díky moc, holt měl jsem to nechat v hlavě vyhnít trochu déle, ještě než jsem se zeptal.
[19] omlouvam se, mate samozrejme pravdu stejne, jako rADo, za tento "prehmat" jsem utrzil 3 zaporne hlasy v karme, nyni uz budu ostrazitejsi.
Zdravím, páni, vysvetlené pekne, ale mohly ste sen dat nejaký ten solution ako to zmenit na servery. Po par hodinách googlení a hladaní som na to prisiel:)
takze treba zmenit umask na 0000 v suboroch /etc/profiles a /etc/login.defs a potom pridat riadok umask 0000 do spustacieho scriptu apache (/etc/init.d/apache2)
pak restart apache a frci to.
[24] sorry je to /etc/profile :) pripadne ako to nepojde tak aj subor ~/.bashrc