On Thu, 20 Jun 2002, C. McCohy wrote:

>   it's going about the safe_mode_exec_dir configuration directive, which
> allows php script to execute an external command, which is located in
> specified directory only. This is able only in safe mode, not in "normal
> mode" ..
>
>   What do you think, would it be nice to have this feature outside the
> safe mode? I think it would be _very_ nice for some security reasons ...

OK, no answer is better than the negative one ;-)))
The patch follows ... I've tested it many times, should work fine ...

It provides the "exec_dir" configuration directive which allows user to
execute external commands located only in specified directory, if safe
mode is disabled. If safe mode is enabled, this directive is forgotten and
safe_mode_exec_dir will be used instead.

So if you think it is a good idea, add it ...

--
Bye .. C. McCohy

The killings will not stop until you Karel Roden

-----------------------------------------------------------------------
diff -uar php-4.2.1.orig/ext/standard/exec.c php-4.2.1/ext/standard/exec.c
--- php-4.2.1.orig/ext/standard/exec.c  Thu Apr 25 16:02:51 2002
+++ php-4.2.1/ext/standard/exec.c       Fri Jun 21 08:48:51 2002
@@ -111,6 +111,50 @@
                        return -1;
                }

+       } else if (PG(exec_dir)) {
+               /* _NO_ safe mode with exec_dir enabled */
+
+               d = emalloc(strlen(PG(exec_dir)) + strlen(cmd) + 2);
+               c = strchr(cmd, ' ');
+               if (c) *c = '\0';
+               if (strstr(cmd, "..")) {
+                       php_error(E_WARNING, "No '..' components allowed in path");
+                       efree(d);
+                       efree(buf);
+                       return -1;
+               }
+               b = strrchr(cmd, PHP_DIR_SEPARATOR);
+               strcpy(d, PG(exec_dir));
+               if (b) {
+                       strcat(d, b);
+               } else {
+                       sprintf(d, "%s%c%s", d, PHP_DIR_SEPARATOR, cmd);
+               }
+               if (c) {
+                       *c = ' ';
+                       strcat(d, c);
+               }
+               tmp = php_escape_shell_cmd(d);
+               efree(d);
+               d = tmp;
+
+#if PHP_SIGCHILD
+               sig_handler = signal (SIGCHLD, SIG_DFL);
+#endif
+#ifdef PHP_WIN32
+               fp = VCWD_POPEN(d, "rb");
+#else
+               fp = VCWD_POPEN(d, "r");
+#endif
+               if (!fp) {
+                       php_error(E_WARNING, "Unable to fork [%s]", d);
+                       efree(d);
+                       efree(buf);
+#if PHP_SIGCHILD
+                       signal (SIGCHLD, sig_handler);
+#endif
+                       return -1;
+               }
        } else { /* not safe_mode */
 #if PHP_SIGCHILD
                sig_handler = signal (SIGCHLD, SIG_DFL);
@@ -122,6 +166,7 @@
 #endif
                if (!fp) {
                        php_error(E_WARNING, "Unable to fork [%s]", cmd);
+                       efree(d);
                        efree(buf);
 #if PHP_SIGCHILD
                        signal (SIGCHLD, sig_handler);
@@ -129,6 +174,7 @@
                        return -1;
                }
        }
+
        buf[0] = '\0';
        if (type==2) {
                if (Z_TYPE_P(array) != IS_ARRAY) {
@@ -453,13 +499,48 @@
        }

        convert_to_string_ex(cmd);
+
+       if(PG(exec_dir)) {
+               char *d, *b;
+               b = strchr(Z_STRVAL_PP(cmd), ' ');
+               if (!b) {
+                       b = strrchr(Z_STRVAL_PP(cmd), PHP_DIR_SEPARATOR);
+               } else {
+                       char *c;
+                       c = Z_STRVAL_PP(cmd);
+                       while ((*b != PHP_DIR_SEPARATOR) && (b != c)) {
+                               b--;
+                       }
+                       if (b == c) {
+                               b = NULL;
+                       }
+               }
+
+               d = emalloc(Z_STRLEN_PP(cmd) + strlen(PG(exec_dir)) + 2);
+               if (b) {
+                       strcpy(d, PG(exec_dir));
+                       strcat(d, b);
+               } else {
+                       sprintf(d, "%s%c%s", PG(exec_dir), PHP_DIR_SEPARATOR, 
+Z_STRVAL_PP(cmd));
+               }
+
 #ifdef PHP_WIN32
-       if ((in=VCWD_POPEN(Z_STRVAL_PP(cmd), "rt"))==NULL) {
+               if ((in=VCWD_POPEN(d, "rt"))==NULL) {
 #else
-       if ((in=VCWD_POPEN(Z_STRVAL_PP(cmd), "r"))==NULL) {
+               if ((in=VCWD_POPEN(d, "r"))==NULL) {
 #endif
-               php_error(E_WARNING, "Unable to execute '%s'", Z_STRVAL_PP(cmd));
-               RETURN_FALSE;
+                       php_error(E_WARNING, "Unable to execute '%s'", d);
+                       RETURN_FALSE;
+               }
+       } else {
+#ifdef PHP_WIN32
+               if ((in=VCWD_POPEN(Z_STRVAL_PP(cmd), "rt"))==NULL) {
+#else
+               if ((in=VCWD_POPEN(Z_STRVAL_PP(cmd), "r"))==NULL) {
+#endif
+                       php_error(E_WARNING, "Unable to execute '%s'", 
+Z_STRVAL_PP(cmd));
+                       RETURN_FALSE;
+               }
        }
        allocated_space = EXEC_INPUT_BUF;
        ret = (char *) emalloc(allocated_space);
diff -uar php-4.2.1.orig/ext/standard/file.c php-4.2.1/ext/standard/file.c
--- php-4.2.1.orig/ext/standard/file.c  Sun May 12 18:08:31 2002
+++ php-4.2.1/ext/standard/file.c       Fri Jun 21 08:25:52 2002
@@ -722,6 +722,34 @@
                        php_error(E_WARNING, "popen(\"%s\", \"%s\") - %s", buf, p, 
strerror(errno));
                        RETURN_FALSE;
                }
+        } else if (PG(exec_dir)) {
+               b = strchr(Z_STRVAL_PP(arg1), ' ');
+               if (!b) {
+                       b = strrchr(Z_STRVAL_PP(arg1), PHP_DIR_SEPARATOR);
+               } else {
+                       char *c;
+                       c = Z_STRVAL_PP(arg1);
+                       while ((*b != PHP_DIR_SEPARATOR) && (b != c)) {
+                               b--;
+                       }
+                       if (b == c) {
+                               b = NULL;
+                       }
+               }
+               if (b) {
+                       snprintf(buf, sizeof(buf), "%s%s", PG(exec_dir), b);
+               } else {
+                       snprintf(buf, sizeof(buf), "%s%c%s", PG(exec_dir), 
+PHP_DIR_SEPARATOR, Z_STRVAL_PP(arg1));
+               }
+
+               tmp = php_escape_shell_cmd(buf);
+               fp = VCWD_POPEN(tmp, p);
+               efree(tmp);
+
+               if (!fp) {
+                       php_error(E_WARNING, "popen(\"%s\", \"%s\") - %s", buf, p, 
+strerror(errno));
+                       RETURN_FALSE;
+               }
        } else {
                fp = VCWD_POPEN(Z_STRVAL_PP(arg1), p);
                if (!fp) {
diff -uar php-4.2.1.orig/main/main.c php-4.2.1/main/main.c
--- php-4.2.1.orig/main/main.c  Sat Mar  9 01:26:40 2002
+++ php-4.2.1/main/main.c       Thu Jun 20 12:06:26 2002
@@ -259,6 +259,7 @@
        PHP_INI_ENTRY("max_execution_time",                     "30",           
PHP_INI_ALL,                    OnUpdateTimeout)
        STD_PHP_INI_ENTRY("open_basedir",                       NULL,           
PHP_INI_SYSTEM,         OnUpdateStringUnempty,  open_basedir,                   
php_core_globals,       core_globals)
        STD_PHP_INI_ENTRY("safe_mode_exec_dir",         "1",            
PHP_INI_SYSTEM,         OnUpdateString,                 safe_mode_exec_dir,            
 php_core_globals,       core_globals)
+       STD_PHP_INI_ENTRY("exec_dir",                   NULL,           
+PHP_INI_SYSTEM,         OnUpdateString,                 exec_dir,                     
+  php_core_globals,       core_globals)
        STD_PHP_INI_ENTRY("upload_max_filesize",        "2M",           PHP_INI_ALL,   
         OnUpdateInt,                    upload_max_filesize,    php_core_globals,     
  core_globals)
        STD_PHP_INI_ENTRY("file_uploads",                       "1",            
PHP_INI_ALL,            OnUpdateBool,                   file_uploads,                  
 php_core_globals,       core_globals)
        STD_PHP_INI_ENTRY("post_max_size",                      "8M",           
PHP_INI_SYSTEM,         OnUpdateInt,                    post_max_size,                 
 sapi_globals_struct,sapi_globals)
diff -uar php-4.2.1.orig/main/php_globals.h php-4.2.1/main/php_globals.h
--- php-4.2.1.orig/main/php_globals.h   Thu Feb 28 09:27:03 2002
+++ php-4.2.1/main/php_globals.h        Thu Jun 20 09:49:14 2002
@@ -69,6 +69,7 @@
        char *unserialize_callback_func;

        char *safe_mode_exec_dir;
+       char *exec_dir;

        long memory_limit;

diff -uar php-4.2.1.orig/php.ini-dist php-4.2.1/php.ini-dist
--- php-4.2.1.orig/php.ini-dist Mon Apr  8 03:15:16 2002
+++ php-4.2.1/php.ini-dist      Thu Jun 20 17:25:53 2002
@@ -390,6 +390,11 @@
 ; cause security issues, KNOW WHAT YOU ARE DOING FIRST.
 ; cgi.redirect_status_env = ;

+; Only executables located in the exec_dir will be allowed to be executed
+; via the exec family of functions. If safe_mode is enabled, this directive
+; is forgotten and safe_mode_exec_dir takes the ride
+exec_dir =
+
 ;;;;;;;;;;;;;;;;
 ; File Uploads ;
 ;;;;;;;;;;;;;;;;
diff -uar php-4.2.1.orig/php.ini-recommended php-4.2.1/php.ini-recommended
--- php-4.2.1.orig/php.ini-recommended  Wed Apr 24 03:51:50 2002
+++ php-4.2.1/php.ini-recommended       Thu Jun 20 17:26:24 2002
@@ -395,7 +395,10 @@
 ; cause security issues, KNOW WHAT YOU ARE DOING FIRST.
 ; cgi.redirect_status_env = ;

-
+; Only executables located in the exec_dir will be allowed to be executed
+; via the exec family of functions. If safe_mode is enabled, this directive
+; is forgotten and safe_mode_exec_dir takes the ride
+exec_dir =

 ;;;;;;;;;;;;;;;;
 ; File Uploads ;


-- 
PHP Development Mailing List <http://www.php.net/>
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to