sys obtenir temp dir dans l'environnement d'hébergement partagé

Note: cela pourrait aussi s'appliquer à superuser.

je configure PHP 5.3.10 sur un hôte partagé avec apache2 mpm itk et open_basedir d'une manière telle que chaque utilisateur ne puisse pas voir ou modifier les fichiers d'un autre utilisateur. Dans les paramètres vhost d'apache2, j'Ajoute 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 l'utilisateur linux à utiliser pour apache2, les trois lignes suivantes définissent le basedir, téléchargez le répertoire et la session savepath pour être dans le répertoire utilisateur. Je reviens à la dernière ligne dans une seconde.

maintenant pour le problème: sys_get_temp_dir() devrait rendre le répertoire temporaire pour php, qui est /tmp par défaut sur un système linux. Pour des raisons de sécurité, ce répertoire devrait se trouver dans l'open_basedir de userA. Selon la source php du 5.3.10, la fonction sys_get_temp_dir() 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() renvoie simplement le répertoire système global, ignorant la variable d'environnement (qui est parfaitement positionnée dans $_SERVER, également visible via phpinfo() ).

il en résulte des bugs désagréables avec divers logiciels utilisant sys_get_temp_dir() , car ce répertoire est en dehors du paramètre open_basedir . J'ai essayé de mettre la variable directement dans $_ENV et $_SERVER sans changement de comportement. J'ai essayé un putenv('TMPDIR=/home/userA/www/tmp') sans changement.

cependant, je suis capable de changer la sortie en définissant la variable en /etc/apache2/envvars - ce qui est inutile pour moi, car je veux que chaque serveur virtuel ait son propre dossier temporaire.

la seule solution que j'ai trouvée jusqu'à présent est de remplacer le sys_get_temp_dir() interne par 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: y a-t-il un moyen de changer le résultat de sys_get_temp_dir() pour être défini dans un paramètre vhost apache2, sans réimplémenter la fonction avec runkit?

Edit: la version apache est 2.2.22, et j'utilise actuellement mod_php. Comme je vais devoir ajouter tous les utilisateurs manuellement, un fcgi ou similaire, installation serait également possible.

21
demandé sur Lars 2012-11-02 01:50:30

7 réponses

Running putenv('TMPDIR=/foo/bar') à l'intérieur PHP semble être en mesure d'affecter le résultat de sys_get_temp_dir() . Vous pourriez avoir une directive auto_prepend_file arrangée pour exécuter un morceau de PHP pour mettre en place le TMPDIR et éviter de jouer avec une redéfinition de sys_get_temp_dir() .

Edit: en outre, vous pouvez facilement utiliser putenv('TMPDIR='.ini_get('open_basedir').'/tmp') pour définir le répertoire temporaire à la structure de répertoire que vous avez présenté dans la question.

assez drôle, il s'avère que cela fonctionne aussi (étant donné que vous conservez le SetEnv TMPDIR /foo/bar dans votre configuration Apache):

putenv('TMPDIR='.getenv('TMPDIR'));

semble comme un no-op, mais en fait ne ont un effet sur sys_get_temp_dir() . Je commence à soupçonner que cela doit être un bug de gestion de L'environnement dans PHP.

22
répondu lanzz 2012-11-07 11:34:21

Vous ont marqués votre question , cependant vous faites usage de

 php_admin_value  open_basedir      /home/userA/www/
 ^^^^^^^^^^^^^^^

qui est un paramètre pour la version de module apache de PHP, Mod_PHP . Dans ce cas, PHP est chargé dès que le serveur web démarre.

alors vous utilisez SetEnv :

 SetEnv           TMPDIR            /home/userA/www/tmp/

ce paramètre définit un environnement interne variable. Il est passé à d'autres modules apache, mais je pense que vous en avez besoin avec la requête, pas avec le serveur virtuel. Je ne le sais pas spécifiquement, mais je suppose selon votre description que cette variable d'environnement est réinitialisée avant que le script PHP ne soit invoqué.

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 pour définir des variables d'environnement pour 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é.


il se peut aussi que vous ne définissiez pas la bonne variable d'environnement. Selon la Documentation Apache sur variables d'environnement :

Bien que ces variables sont appelées variables d'environnement , ils ne sont pas les mêmes que les variables d'environnement contrôlées par le système d'exploitation. Au lieu de cela, ces variables sont stockées et manipulées dans une structure interne D'Apache. Elles ne deviennent de véritables variables d'environnement du système d'exploitation que lorsqu'elles sont fournies aux scripts CGI et aux scripts Include du côté du serveur. Si vous vous souhaitez manipuler l'environnement du système d'exploitation dans lequel le serveur lui-même tourne, vous devez utiliser les mécanismes standard de manipulation de l'environnement fournis par votre shell du système d'exploitation.

vous voulez définir la variable d'environnement du système d'exploitation pour PHP. Mais vous définissez seulement la variable d'environnement interne.

Mod_PHP pourrait les importer dans le script, donc si vous utilisez getenv('TMPDIR') le PHP SAPI une implémentation spécifique est utilisée - ce qui vous permet de voir ces variables d'environnement internes - mais la fonction php_get_temporary_directory ne l'utilise pas - on dirait.

veuillez ajouter votre version Apache et PHP à votre question.

6
répondu hakre 2012-11-07 13:03:38

selon ce bogue de 4 ans , sys_get_temp_dir() ne fonctionnera pas avec les serveurs virtuels; donc

  • vous pouvez essayer d'utiliser seulement les bibliothèques qui ont corrigé ce problème (et ouvrir un bug pour ceux qui ne l'ont pas fait)
  • ou ajouter /tmp (ou tout ce que votre système d'exploitation utilise) dans votre open_basedir , comme il peut contenir plusieurs répertoires (comme include_path - le séparer avec ; sur Windows, : autres)
5
répondu pozs 2012-11-09 23:27:39

en regardant les source PHP , sys_get_temp_dir() fonctionne avec la priorité suivante:

  1. si sa valeur a déjà été calculée, la valeur en cache est utilisée.
  2. sys_temp_dir est vérifié dans la configuration ini.
  3. sous Windows, la méthode de L'API GetTempPathW Win32 est utilisée, et selon sa documentation les éléments suivants sont utilisés (dans cet ordre:):
    1. le chemin spécifié par la variable d'environnement TMP .
    2. le chemin spécifié par la variable d'environnement TEMP .
    3. le chemin spécifié par la variable d'environnement USERPROFILE .
    4. le répertoire de Windows.
  4. sous *nix, les éléments suivants sont utilisés (dans cet ordre):
    1. Le TMPDIR variable d'environnement.
    2. Le P_tmpdir macro
    3. /tmp (selon la source, il s'agit d'un dernier effort qui ne devrait jamais se produire).

qui devrait vous donner assez d'options pour contrôler le résultat de sys_get_temp_dir (par exemple ini_set('sys_temp_dir', $tmpPath) ou putenv('TMPDIR=/foo/bar') comme d'autres mentionnés) à moins que il a été calculé précédemment, dans lequel cas vous êtes SOL autant que je sais et la valeur mise en cache sera utilisée (mais je n'ai aucune connaissance en PHP, donc j'aimerais l'entendre autrement).

3
répondu Ohad Schneider 2017-08-20 22:18:48

il s'agit d'un bug dans php 5.2 - spécifie temp dir par php.ini

Il est fixé à 5.5

Utilisez ceci comme solution temporaire:

<?php
putenv('TMPDIR=/path/to/your/tmp');
          ...your code here ...
?>
1
répondu eugene 2014-03-29 00:14:17

au cas où des gens se retrouveraient ici dont le problème n'est pas résolu avec putenv...

... pour moi, il a fonctionné pour définir le sys_temp_dir en utilisant php ini_set comme ceci:

$tmpPath = realpath(__DIR__.'/../app/tmp');
ini_set('sys_temp_dir', $tmpPath);

J'exécute PHP 5.5.9 (cli) sur une machine windows8.

1
répondu Andresch Serj 2014-06-04 08:48:52

on dirait que vous pouvez changer la valeur retournée par sys_get_temp_dir() , je viens d'essayer apache 2.4 et php 5.6.27.

Ajouter un sys_temp_dir dans le virtualhost:

php_admin_value sys_temp_dir "/var/www/alternc/f/fser/tmp"

redémarrez apache, et imprimez la valeur dans une page Web en utilisant sys_get_temp_dir() :

<?php 
echo sys_get_temp_dir () ;

produit le résultat attendu: /var/www/alternc/f/fser/tmp .

0
répondu Aif 2016-10-28 16:03:39