sys_get_temp_dir dans l'environnement d'hébergement partagé
Remarque: Ce problème peut également s'adapter en super-utilisateur.
Je suis la configuration de PHP 5.3.10 sur un ordinateur hôte partagé avec apache2 mpm itk et open_basedir de manière à ce que chaque utilisateur ne peut pas voir ou modifier les fichiers d'un autre utilisateur. Dans le apache2 vhost réglages, j'ai ajouter les entrées appropriées pour restreindre l'utilisateur:
AssignUserId userA userA
php_admin_value open_basedir /home/userA/www/
php_admin_value upload_tmp_dir /home/userA/www/tmp/
php_admin_value session.save_path /home/userA/www/tmp/
SetEnv TMPDIR /home/userA/www/tmp/
Maintenant, la première ligne définit les utilisateurs de linux à utiliser pour apache2, les trois lignes suivantes définissent les basedir, répertoire de téléchargement et de la session savepath être dans le répertoire de l'utilisateur. Je vais revenir à la dernière ligne en une seconde.
Maintenant pour le problème: sys_get_temp_dir()
devrait redonner le répertoire temporaire pour php, qui est /tmp être par défaut sur un système linux. Pour des raisons de sécurité, ce répertoire doit résider dans le open_basedir de l'utilisateur. Selon le php-source de 5.3.10, le sys_get_temp_dir()
-fonction utilise la variable d'environnement TMPDIR pour obtenir ce répertoire:
//php-src/main/php_open_temporary_file.c:217-219
/* On Unix use the (usual) TMPDIR environment variable. */
{
char* s = getenv("TMPDIR");
C'est ce que la cinquième ligne dans la configuration ci-dessus devrait faire. Cependant, sys_get_temp_dir()
retourne simplement le système global directory, ignorant la variable d'environnement (ce qui est parfaitement défini dans la variable $_SERVER, également visible via phpinfo()
).
Cette résultats dans quelques vilains bugs avec divers logiciels en s'appuyant sur sys_get_temp_dir()
, que ce répertoire est à l'extérieur de la open_basedir
réglage. J'ai essayé de définir la variable directement dans $_ENV et $_SERVER sans un changement de comportement. J'ai essayé un putenv('TMPDIR=/home/userA/www/tmp')
sans changement.
Cependant, je suis en mesure de changer la sortie en définissant la variable dans /etc/apache2/envvars - ce qui est inutile pour moi, car je veux que chaque VHOST pour avoir son propre dossier temporaire.
La seule solution que j'ai trouvé pour l'instant est d'écraser l'intérieur sys_get_temp_dir()
grâce à une extension comme runkit et l'application de son inclusion via auto_prepend_file. Mais cette solution est tellement sale, je ne peux pas le croire, qu'il n'y a pas de meilleure solution.
Donc, ma question: Est-il possible de modifier le résultat de sys_get_temp_dir()
à être installé dans un apache2 vhost, sans réimplanter la fonction avec runkit?
Edit: La version d'apache est 2.2.22, et actuellement, je utiliser mod_php. Comme je vais devoir ajouter tous les utilisateurs manuellement, un fcgi ou similaire, installation serait également possible.
- Qui Apache version utilisez-vous? 2.0? 2.2? 2.4?
- Simplement être informé que
open_basedir
peut être très coûteux. J'ai vu des situations où les temps de chargement des pages d'un complexe CMS backend (TYPO3) a augmenté de 3 secondes >50 secondes en vertu de la directive open_basedir de protection.
Vous devez vous connecter pour publier un commentaire.
De l'exécution d'un
putenv('TMPDIR=/foo/bar')
à l'intérieur de PHP semble être en mesure d'affecter le résultat desys_get_temp_dir()
. Vous pourriez avoir uneauto_prepend_file
directive disposés à exécuter un morceau de PHP pour configurer leTMPDIR
et éviter de jouer avec une redéfinition desys_get_temp_dir()
.Edit: Aussi, vous pouvez facilement utiliser
putenv('TMPDIR='.ini_get('open_basedir').'/tmp')
pour définir le répertoire temporaire de la structure de répertoire que vous avez posé dans la question.Assez drôle, cela s'avère aussi travail (étant donné que vous gardez le
SetEnv TMPDIR /foo/bar
dans votre configuration d'Apache):Semble comme un no-op, mais en fait ne ont un effet sur
sys_get_temp_dir()
. Je commence à soupçonner que cela a à être certains de l'environnement de la manipulation de bug dans PHP.<?php putenv('TMPDIR=/foo/bar'); print(sys_get_temp_dir());
, sorties/foo/bar
dans le navigateur.<php echo sys_get_temp_dir(); putenv('TMPDIR=/foo'); echo sys_get_temp_dir(); ?>
. Toutefois, php caches de la sortie desys_get_temp_dir()
(étrangement également affecté par unclearstatcache(true, true)
). Donc, à l'aide de votre méthode, j'ai toujours le besoin d'injecter un script php à l'avant. Chaque utilisateur doit obtenir son propre, soit je dois donner à chaque utilisateur un php personnalisé.ini par le php.ini de la politique ou de construire une fonction pour trouver l'utilisateur et de remplacer le builtinsys_get_temp_dir()
. Merci pour la réponse si loin!putenv('TMPDIR='.ini_get('upload_tmp_dir'))
pour tous les utilisateurs?upload_tmp_dir
devrait déjà être défini à ce point. Ou'TMPDIR='.ini_get('open_basedir').'/tmp'
, pour être le plus sémantiquement correct.PG(php_sys_temp_dir)
dansphp_open_temporary_file.c
: github.com/php/php-src/blob/....Vous ont marqués votre question cgi, cependant, vous êtes faisant usage de
qui est un paramètre du module apache version de PHP, Mod_PHP. Dans ce cas, PHP est chargé une fois le serveur web démarre.
Puis vous faites usage de
SetEnv
:c'est la fixation d'un interne variable d'environnement. Il est passé à d'autres modules d'apache, mais je pense que vous en avez besoin à la demande, et non pas avec le serveur virtuel. Je ne sais pas précisément, mais je suppose que selon votre description cette variable d'environnement est d'arriver à zéro avant le script PHP est invoquée.
Donc plus un commentaire qu'une vraie réponse, mais j'espère qu'il vous aide à clarifier certaines choses.
J'utilise normalement FCGI pour les environnements multi-utilisateurs afin que je puisse mieux séparer les utilisateurs. Je n'ai jamais eu de problèmes avec la définition des variables d'environnement par chaque utilisateur. Mais c'est juste un autre commentaire, je ne veux pas dire que vous avez à utiliser, aussi. Juste pour souligner que vous devez trouver le bon endroit dans apache pour définir la variable d'environnement de sorte qu'il est (encore) ensemble lorsque le script est exécuté.
Aussi que vous pourriez ne pas être en paramètre le droit de la variable d'environnement. Selon Documentation d'Apache sur les variables d'environnement:
Vous souhaitez définir le système d'exploitation variable d'environnement pour PHP. Mais vous êtes réglage interne de la variable d'environnement uniquement.
Mod_PHP peut les importer dans le script, donc si vous utilisez
getenv('TMPDIR')
le PHP SAPI spécifiques de mise en œuvre est utilisée - ce qui ne vous permet pas de voir ceux des variables d'environnement internes - cependant lephp_get_temporary_directory
fonction n'est pas à l'utiliser - il ressemble.S'il vous plaît ajouter votre Apache et PHP version à votre question.
mod_php
scénario, sinon pas de module de poignée de laphp_admin_value
directives et Apache serait se plaindre non valide directives dans sa configuration.mod_php
scénario. La question intéressante est de savoir comment définir une variable d'environnement avec Apache qui est traduit par un script PHP qui est appelé par l'intermédiaire demod_php
.mod_php
d'exécution au script PHP; il y a quelques apparente mauvaise gestion de cette variable si —getenv('TMPDIR')
renvoie la valeur correcte affecté dans Apache, maissys_get_temp_dir()
ne voit que la valeur correcte après avoir faitputenv('TMPDIR='.getenv('TMPDIR'))
putenv
permettra de résoudre ce problème. Avez-vous été en mesure de reproduire ce que l'OP décrit dans la question?TMPDIR
variable avant le premier appel àphp_get_temporary_directory
. Le problème est quegetenv('TMPDIR')
en PHP renvoie une valeur différente (la bonne) que lagetenv("TMPDIR")
à la ligne 219 dansphp_open_temporary_file.c
(qui renvoie une valeur incorrecte), moinsputenv('TMPDIR='.getenv('TMPDIR'))
a été appelé en PHP en premier.SetEnv
à la variable d'environnement système en premier. Je ne peux pas reproduire le problème ici, mais cela pourrait être le cas.getenv('TMPDIR')
a pas de problèmes pour récupérer la valeur définie avecSetEnv
dans la configuration d'Apache, c'est à dire qu'il est correctement exportés et accessible à l'intérieur du script PHP. Le problème est avecgetenv
C n'étant pas en mesure d'accéder à cette même valeur.getenv
est capable de lire également internes d'apache, les variables d'environnement comme par le SAPI mise en œuvre - alors il faudrait lire le SetEnv variable, cependant ce n'est pas une variable d'environnement système alors.Selon ce - 4 ans - bug,
sys_get_temp_dir()
ne fonctionne pas avec les hôtes virtuels; de sorte/tmp
(ou quel que soit votre système d'exploitation utilise le) dans votreopen_basedir
, comme il peut contenir plusieurs répertoires (commeinclude_path
- il se séparer avec;
sur Windows,:
contraire)À la recherche à la Source PHP,
sys_get_temp_dir()
travaille avec l'ordre de priorité suivant:sys_temp_dir
est coché dans la configuration ini.TMP
variable d'environnement.TEMP
variable d'environnement.USERPROFILE
variable d'environnement.TMPDIR
variable d'environnement.P_tmpdir
macro/tmp
(selon la source, c'est un ultime effort qui ne devrait jamais arriver).Qui devrait vous donner suffisamment d'options pour contrôler le résultat de
sys_get_temp_dir
(par exempleini_set('sys_temp_dir', $tmpPath)
ouputenv('TMPDIR=/foo/bar')
comme d'autres l'ont mentionné) Sauf il a été calculée précédemment, dans ce cas, vous êtes SOL autant que je sache, et la valeur mise en cache sera utilisé (mais je n'ai aucune connaissance en PHP, ce serait l'amour d'entendre le contraire).C'est un bug dans php 5.2 - spécifier temp dir par php.ini
Il est fixé à 5.5
Utiliser cela comme une solution temporaire:
Dans le cas où les gens se retrouvent ici whos Problème n'est pas résolu avec putenv...
... pour moi, il a travaillé pour définir la
sys_temp_dir
aide de phpini_set
comme ceci:Je suis en cours d'exécution PHP 5.5.9 (cli) sur un windows8 machine.
Il semble que vous pouvez changer la valeur retournée par
sys_get_temp_dir()
, j'ai juste essayé sur apache 2.4 et php 5.6.27.Ajouter un
sys_temp_dir
dans le virtualhost:De redémarrer apache et imprimer la valeur dans une page web à l'aide de
sys_get_temp_dir()
:Produit le résultat attendu:
/var/www/alternc/f/fser/tmp
.