2012-11-01 4 views
21

नोट: यह सुपरसियर में भी फिट हो सकता है।sys_get_temp_dir

मैं एक साझा मेजबान पर apache2 mpm itk और open_basedir के साथ PHP 5.3.10 सेट अप कर रहा हूं, कि प्रत्येक उपयोगकर्ता किसी अन्य उपयोगकर्ता की फ़ाइलों को देख या परिवर्तित नहीं कर सकता है। apache2 vhost सेटिंग्स में, मैं उपयोगकर्ता को प्रतिबंधित करने के लिए उपयुक्त प्रविष्टियों जोड़ें:

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/ 

अब, पहली पंक्ति apache2 के लिए उपयोग करने के लिए लिनक्स उपयोगकर्ता, अगले तीन लाइनों basedir, अपलोड निर्देशिका और सत्र savepath परिभाषित सेट उपयोगकर्ता निर्देशिका में होना है। मैं एक सेकंड में अंतिम पंक्ति पर वापस आऊंगा।

अब समस्या के लिए: sys_get_temp_dir() को PHP के लिए अस्थायी निर्देशिका वापस देनी चाहिए, जो एक लिनक्स सिस्टम पर/tmp डिफ़ॉल्ट है। सुरक्षा कारणों से, यह निर्देशिका उपयोगकर्ता ए के open_basedir में रहनी चाहिए। 5.3.10 के php-स्रोत के अनुसार, sys_get_temp_dir() समारोह वातावरण चर TMPDIR का उपयोग करता है इस निर्देशिका पाने के लिए:

 // php-src/main/php_open_temporary_file.c:217-219 
    /* On Unix use the (usual) TMPDIR environment variable. */ 
    { 
      char* s = getenv("TMPDIR"); 

यह वही विन्यास में पांचवें रेखा से ऊपर क्या करना चाहिए है। हालांकि, sys_get_temp_dir() पर्यावरण परिवर्तक को अनदेखा कर देता है, जो पूरी तरह से $ _SERVER में सेट है, phpinfo() के माध्यम से भी देखने योग्य है)।

परिणामस्वरूप sys_get_temp_dir() पर निर्भर विभिन्न सॉफ़्टवेयर के साथ कुछ गड़बड़ियां होती हैं, क्योंकि यह निर्देशिका open_basedir सेटिंग से बाहर है। मैंने वैरिएबल को व्यवहार में बदलाव किए बिना सीधे $ _ENV और $ _SERVER में सेट करने का प्रयास किया है। मैंने बिना किसी परिवर्तन के putenv('TMPDIR=/home/userA/www/tmp') की कोशिश की है।

हालांकि, मैं चर को/etc/apache2/envvars में परिभाषित करके आउटपुट को बदलने में सक्षम हूं - जो मेरे लिए बेकार है, क्योंकि मैं चाहता हूं कि प्रत्येक VHOST का अपना अस्थायी फ़ोल्डर हो।

एकमात्र समाधान मैं अब तक runkit जैसा कोई एक्सटेंशन के माध्यम से आंतरिक sys_get_temp_dir() अधिलेखन और auto_prepend_file के माध्यम से अपने शामिल किए जाने के लागू कर रहा है मिल गया है। लेकिन वह समाधान इतना गंदा है, मैं बस विश्वास नहीं कर सकता, कि चारों ओर कोई बेहतर समाधान नहीं है।

तो, मेरा प्रश्न: क्या sys_get_temp_dir() के परिणाम को अपाचे 2 vhost सेटिंग में सेट करने के लिए कोई तरीका है, बिना रनकिट के फ़ंक्शन को पुन: कार्यान्वित किए?

संपादित करें: अपाचे संस्करण 2.2.22 है, और मैं वर्तमान में mod_php का उपयोग करता हूं। चूंकि मुझे मैन्युअल रूप से सभी उपयोगकर्ताओं को जोड़ना होगा, एक एफसीजीआई या इसी तरह का सेटअप भी संभव होगा।

+0

आप किस अपाचे संस्करण का उपयोग कर रहे हैं? 2.0? 2.2? 2.4? – hakre

+1

बस सूचित किया जाए कि 'open_basedir'' वास्तव में महंगा हो सकता है। मैंने परिस्थितियों को देखा है जहां एक जटिल सीएमएस बैकएंड (TYPO3) के पृष्ठ लोड समय open_basedir सुरक्षा के तहत 3 सेकंड से> 50 सेकंड तक बढ़ गए हैं। – Jpsy

उत्तर

21

putenv('TMPDIR=/foo/bar') के अंदर sys_get_temp_dir() के परिणाम को प्रभावित करने में सक्षम होने लगता है। आपके पास निर्देश TMPDIR सेट करने के लिए PHP के एक टुकड़े को चलाने के लिए व्यवस्थित किया गया था और sys_get_temp_dir() की पुनर्वितरण के साथ गड़बड़ से बचने के लिए निर्देशित किया गया था।

संपादित करें: इसके अलावा, आप आसानी से इस्तेमाल कर सकते हैं putenv('TMPDIR='.ini_get('open_basedir').'/tmp') निर्देशिका संरचना है कि विचाराधीन बाहर रखी को अस्थायी निर्देशिका स्थापित करने के लिए।

काफी अजीब बात है, इस निकला भी काम करने के लिए (यह देखते हुए कि आप अपने अपाचे विन्यास में SetEnv TMPDIR /foo/bar रखने के लिए):

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

नो-सेशन की तरह लगता है, लेकिन वास्तव में करताsys_get_temp_dir() पर प्रभाव है। मुझे संदेह है कि PHP में कुछ पर्यावरण-हैंडलिंग बग होना चाहिए।

+0

यह मेरे लिए नहीं है (जैसा कि मैंने प्रश्न में लिखा है और अभी पुनः जांच की है)। यदि यह आपके लिए करता है, तो क्या आप कृपया php- और apache-version निर्दिष्ट कर सकते हैं जिसका आप उपयोग कर रहे हैं? – Lars

+0

मुझे अपाचे 2.2.17 और PHP 5.3.16 चल रहा है। टेस्ट कोड: ' lanzz

+0

मेरे 5.3.10 के बाद से इस फ़ंक्शन के साथ कुछ भी नहीं बदला है - आप किस ओएस पर परीक्षण कर रहे हैं? – Lars

6

आप अपने प्रश्न में चिह्नित है, लेकिन आप जो PHP के अपाचे मॉड्यूल संस्करण, mod_php के लिए एक सेटिंग है

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

के उपयोग कर रहे हैं। वेबसर्वर शुरू होने के बाद उस मामले में PHP लोड हो जाता है।

तो फिर तुम SetEnv का इस्तेमाल करते हैं:

SetEnv   TMPDIR   /home/userA/www/tmp/ 

यह एक आंतरिक वातावरण चर स्थापित कर रही है। यह अन्य अपाचे मॉड्यूल को पास किया जाता है, हालांकि मुझे लगता है कि आपको अनुरोध के साथ इसकी आवश्यकता है, वर्चुअल सर्वर के साथ नहीं। मैं इसे विशेष रूप से नहीं जानता, लेकिन मैं आपके वर्णन के अनुसार मानता हूं कि PHP स्क्रिप्ट लागू होने से पहले यह पर्यावरण चर रीसेट हो रहा है।

वास्तविक उत्तर से अधिक टिप्पणी, लेकिन उम्मीद है कि यह आपको कुछ चीजों को स्पष्ट करने में मदद करता है।

मैं आम तौर पर बहु-उपयोगकर्ता वातावरण के लिए एफसीजीआई का उपयोग करता हूं ताकि मैं उपयोगकर्ताओं को बेहतर ढंग से अलग कर सकूं। मुझे प्रत्येक उपयोगकर्ता के लिए पर्यावरण चर सेट करने में कभी समस्या नहीं थी। लेकिन यह सिर्फ एक और टिप्पणी है, मैं नहीं कहना चाहता कि आपको इसका भी उपयोग करना है। बस हाइलाइट करने के लिए कि आपको पर्यावरण चर सेट करने के लिए अपाचे के भीतर सही जगह खोजने की आवश्यकता है ताकि स्क्रिप्ट निष्पादित होने पर यह (अभी भी) सेट हो।


इसके अलावा आप सही पर्यावरण चर सेट नहीं कर रहे हैं। Apache Documentation about environment variables के अनुसार:

हालांकि इन चर के रूप में वातावरण चर में भेजा जाता है, वे अंतर्निहित ऑपरेटिंग सिस्टम द्वारा नियंत्रित वातावरण चर के रूप में ही नहीं हैं। इसके बजाय, इन चरों को एक आंतरिक अपाचे संरचना में संग्रहीत और छेड़छाड़ की जाती है। जब वे सीजीआई स्क्रिप्ट्स और सर्वर साइड को स्क्रिप्ट शामिल करते हैं तो वे केवल वास्तविक ऑपरेटिंग सिस्टम पर्यावरण चर बन जाते हैं। यदि आप ऑपरेटिंग सिस्टम पर्यावरण में हेरफेर करना चाहते हैं जिसके तहत सर्वर स्वयं चलता है, तो आपको अपने ऑपरेटिंग सिस्टम शैल द्वारा प्रदान किए गए मानक पर्यावरण मैनिपुलेशन तंत्र का उपयोग करना होगा।

आप PHP के लिए ऑपरेटिंग सिस्टम पर्यावरण चर सेट करना चाहते हैं। लेकिन आप केवल आंतरिक पर्यावरण चर सेट कर रहे हैं।

mod_php उन्हें स्क्रिप्ट के आयात हो सकता है, इसलिए यदि आप getenv('TMPDIR') का उपयोग पीएचपी SAPI के विशिष्ट कार्यान्वयन प्रयोग किया जाता है - लेकिन php_get_temporary_directory समारोह इसे प्रयोग नहीं कर रहा है - - जो आप उन आंतरिक वातावरण चर को देखने के लिए अनुमति नहीं है यह कैसा दिखता ।

कृपया अपने प्रश्न में अपना अपाचे और PHP संस्करण जोड़ें।

+1

यह स्पष्ट रूप से एक 'mod_php' परिदृश्य है, अन्यथा कोई मॉड्यूल' php_admin_value' निर्देशों को संभाल नहीं लेगा और अपाचे इसकी कॉन्फ़िगरेशन में अमान्य निर्देशों के बारे में शिकायत करेगा। – lanzz

+1

जो मैंने लिखा है, हां एक 'mod_php' परिदृश्य। दिलचस्प सवाल यह है कि, अपाचे के साथ एक पर्यावरण परिवर्तक कैसे सेट करें जिसे एक PHP स्क्रिप्ट द्वारा प्रतिबिंबित किया जा रहा है जिसे 'mod_php' के माध्यम से बुलाया जाता है। – hakre

+1

पर्यावरण चर _is_ 'mod_php'-execed PHP स्क्रिप्ट के अंदर उपलब्ध है; यद्यपि उस चर के कुछ स्पष्ट मिशनलिंग हैं - 'getenv (' TMPDIR ')' अपाचे में असाइन किए गए सही मान को वापस लौटाता है, लेकिन 'sys_get_temp_dir()' केवल 'putenv ('TMPDIR ='। getenv ('टीएमपीडीआईआर')) ' – lanzz

5

this - 4 year old - bug के अनुसार, sys_get_temp_dir() वर्चुअल-होस्ट के साथ काम नहीं करेगा; इसलिए

  • आप केवल पुस्तकालयों है कि इस समस्या का समाधान हो (& जो नहीं किया था के लिए एक बग खोलना)
  • , it can hold multiple directories के रूप में उपयोग या /tmp संलग्न (या जो भी अपने OS का उपयोग करता है) अपने open_basedir में करने के लिए कोशिश कर सकते हैं (जैसे include_path - यह ; विंडोज पर से अलग करें, : अन्यथा)
+0

आपके उत्तर के लिए धन्यवाद - दुर्भाग्य से, एकाधिक निर्देशिका विकल्प मेरे लिए भी काम नहीं करता है। मैं इस प्रश्न में इस संभावित समाधान का उल्लेख करना भूल गया। – Lars

+0

@pozs और अब यह * आखिरकार * तय है :) – user11153

1

यह php में एक बग 5.2 है - specify temp dir by php.ini
यह 5.5
में ठीक किया गया है एक अस्थायी समाधान के रूप में इस का उपयोग करें:

<?php 
putenv('TMPDIR=/path/to/your/tmp'); 
      ...your code here ... 
?> 
1

मामले में लोगों अंत यहाँ कौन समस्या putenv के साथ हल नहीं है ...

... मेरे लिए यह php के ini_set का उपयोग कर sys_temp_dir स्थापित करने के लिए काम किया इस तरह:

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

मैं विंडोज 8 मशीन पर PHP 5.5.9 (क्ली) चला रहा हूं।

0

ऐसा लगता है कि आप sys_get_temp_dir() द्वारा दिए गए मान को बदल सकते हैं, मैंने अभी अपाचे 2.4 और PHP 5.6.27 पर कोशिश की है।

वर्चुअलहोस्ट में एक sys_temp_dir जोड़ें:

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

पुनः प्रारंभ अपाचे, और sys_get_temp_dir() का उपयोग कर एक वेब पेज में मूल्य प्रिंट:

<?php 
echo sys_get_temp_dir() ; 

उम्मीद उत्पादन का उत्पादन: /var/www/alternc/f/fser/tmp

3

PHP source को देखते हुए, निम्नलिखित प्राथमिकता के साथ sys_get_temp_dir() काम करता है:

  1. अपने मूल्य से पहले गणना की गई है, तो कैश की गई मूल्य प्रयोग किया जाता है।
  2. sys_temp_dir आईएनआई कॉन्फ़िगरेशन में चेक किया गया है।
  3. Windows पर, GetTempPathW Win32 एपीआई विधि का इस्तेमाल किया, और इसके प्रलेखन निम्नलिखित उपयोग किया जाता है (इस क्रम में) के अनुसार:
    1. पथ TMP वातावरण चर द्वारा निर्दिष्ट।
    2. TEMP पर्यावरण चर द्वारा निर्दिष्ट पथ।
    3. USERPROFILE पर्यावरण चर द्वारा निर्दिष्ट पथ।
    4. विंडोज निर्देशिका।
  4. * nix में, निम्न उपयोग किया जाता है (इस क्रम में):
    1. TMPDIR वातावरण चर।
    2. P_tmpdir मैक्रो
    3. /tmp (स्रोत के अनुसार, यह एक आखिरी प्रयास है कि ऐसा कभी नहीं करना चाहिए)।

कि sys_get_temp_dir (ini_set('sys_temp_dir', $tmpPath) जैसे या putenv('TMPDIR=/foo/bar') के रूप में दूसरों का उल्लेख) जब तक यह पहले से गणना की गई थी, जिस स्थिति में आप एसओएल के रूप में तक मुझे पता है कर रहे हैं का परिणाम नियंत्रित करने के लिए आपके पास पर्याप्त विकल्प देना चाहिए और कैश किए गए मान का उपयोग किया जाएगा (लेकिन मेरे पास PHP में शून्य ज्ञान है इसलिए अन्यथा सुनना अच्छा लगेगा)।