]> granicus.if.org Git - php/commitdiff
Extend open_basedir functionality to allow runtime tightening
authorSara Golemon <pollita@php.net>
Tue, 17 Oct 2006 21:54:17 +0000 (21:54 +0000)
committerSara Golemon <pollita@php.net>
Tue, 17 Oct 2006 21:54:17 +0000 (21:54 +0000)
NEWS
main/fopen_wrappers.c
main/fopen_wrappers.h
main/main.c

diff --git a/NEWS b/NEWS
index b91ea39c326dccae16feb09bea0034199c453456..bc6b7b26a079f1117332588946e1432a1ceacb25 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -10,6 +10,7 @@ PHP                                                                        NEWS
   functions to not call __autoload(). (Dmitry)
 - Changed opendir/dir/scandir to use default context
   when no context argument is passed. (Sara)
+- Changed open_basedir to allow tightening in runtime contexts. (Sara)
 
 - Removed old legacy:
   . "register_globals" support. (Pierre)
index 265097d8baa8630232647da427f9354d2434bb08..7f22be32bab888a6ab054ca0ccf8782f9036af90 100644 (file)
 #endif
 /* }}} */
 
+/* {{{ OnUpdateBaseDir
+Allows any change to open_basedir setting in during Startup and Shutdown events,
+or a tightening during activation/runtime/deactivation */
+PHPAPI ZEND_INI_MH(OnUpdateBaseDir)
+{
+       char **p, *pathbuf, *ptr, *end;
+#ifndef ZTS
+       char *base = (char *) mh_arg2;
+#else
+       char *base = (char *) ts_resource(*((int *) mh_arg2));
+#endif
+
+       p = (char **) (base+(size_t) mh_arg1);
+
+       if (stage == PHP_INI_STAGE_STARTUP || stage == PHP_INI_STAGE_SHUTDOWN) {
+               /* We're in a PHP_INI_SYSTEM context, no restrictions */
+               *p = new_value;
+               return SUCCESS;
+       }
+
+        
+       /* Elsewise, we're in runtime */
+       if (!*p || !**p) {
+               /* open_basedir not set yet, go ahead and give it a value */
+               *p = new_value;
+               return SUCCESS;
+       }
+
+       /* Shortcut: When we have a open_basedir and someone tries to unset, we know it'll fail */
+       if (!new_value || !*new_value) {
+               return FAILURE;
+       }
+
+       /* Is the proposed open_basedir at least as restrictive as the current setting? */
+       ptr = pathbuf = estrdup(new_value);
+       while (ptr && *ptr) {
+               end = strchr(ptr, DEFAULT_DIR_SEPARATOR);
+               if (end != NULL) {
+                       *end = '\0';
+                       end++;
+               }
+               if (php_check_open_basedir_ex(ptr, 0 TSRMLS_CC) != 0) {
+                       /* At least one portion of this open_basedir is less restrictive than the prior one, FAIL */
+                       efree(pathbuf);
+                       return FAILURE;
+               }
+               ptr = end;
+       }
+       efree(pathbuf);
+
+       /* Everything checks out, set it */
+       *p = new_value;
+
+       return SUCCESS;
+}
+/* }}} */
+
+
 /* {{{ php_check_specific_open_basedir
        When open_basedir is not NULL, check if the given filename is located in
        open_basedir. Returns -1 if error or not in the open_basedir, else 0
index fc46f92a6c18721ef9bf9c5e4f9a8b7de074c80e..9a7bfa562b448a250740599f83b7be9877c13d92 100644 (file)
@@ -23,6 +23,7 @@
 
 BEGIN_EXTERN_C()
 #include "php_globals.h"
+#include "php_ini.h"
 
 PHPAPI int php_fopen_primary_script(zend_file_handle *file_handle TSRMLS_DC);
 PHPAPI char *expand_filepath(const char *filepath, char *real_path TSRMLS_DC);
@@ -35,6 +36,8 @@ PHPAPI FILE *php_fopen_with_path(const char *filename, const char *mode, const c
 
 PHPAPI int php_is_url(char *path);
 PHPAPI char *php_strip_url_passwd(char *path);
+
+PHPAPI ZEND_INI_MH(OnUpdateBaseDir);
 END_EXTERN_C()
 
 #endif
index d70451866eed4583a265edfadaa4fef9ccea0e20..e26a740aa85df095588fcde592da88836bb19a7c 100644 (file)
@@ -339,6 +339,7 @@ static PHP_INI_MH(OnUpdateDefaultMimetype)
 #else
 #      define DEFAULT_SENDMAIL_PATH NULL
 #endif
+
 /* {{{ PHP_INI
  */
 PHP_INI_BEGIN()
@@ -392,7 +393,7 @@ PHP_INI_BEGIN()
        STD_PHP_INI_ENTRY("extension_dir",                      PHP_EXTENSION_DIR,              PHP_INI_SYSTEM,         OnUpdateStringUnempty,  extension_dir,                  php_core_globals,       core_globals)
        STD_PHP_INI_ENTRY("include_path",                       PHP_INCLUDE_PATH,               PHP_INI_ALL,            OnUpdateStringUnempty,  include_path,                   php_core_globals,       core_globals)
        PHP_INI_ENTRY("max_execution_time",                     "30",           PHP_INI_ALL,                    OnUpdateTimeout)
-       STD_PHP_INI_ENTRY("open_basedir",                       NULL,           PHP_INI_SYSTEM,         OnUpdateString,                 open_basedir,                   php_core_globals,       core_globals)
+       STD_PHP_INI_ENTRY("open_basedir",                       NULL,           PHP_INI_ALL,            OnUpdateBaseDir,                        open_basedir,                   php_core_globals,       core_globals)
 
        STD_PHP_INI_BOOLEAN("file_uploads",                     "1",            PHP_INI_SYSTEM,         OnUpdateBool,                   file_uploads,                   php_core_globals,       core_globals)
        STD_PHP_INI_ENTRY("upload_max_filesize",        "2M",           PHP_INI_SYSTEM|PHP_INI_PERDIR,          OnUpdateLong,                   upload_max_filesize,    php_core_globals,       core_globals)