Hi,
I want your comments. This patch adds safe_mode awareness to the
ftp extension. It was done against the 4.2.0 tree because there
must be some changes in the extension because of streams and so
i wanted to ensure that it is working first.
This patch modifies:
is_uploaded_file : works now also on files retrieved via ftp_get
move_uploaded_file : works now also on files retrieved via ftp_get
ftp_get: checks safe_mode and openbasedir restrictions and adds downloaded
files to a hashtable
ftp_put: checks safe_mode and openbasedir restrictions
php_checkuid: handles ftp_uploaded files in the same way rfc1867 uploaded
files are handled + FIX: correct output if file does not exist
sapi_deactivate: will remove uploaded files
Stefan
PS: Due to the changes done a few days ago in php_checkuid there will be
a lot of bug reports (i guess) because checkuid is now really strict
diff -ur php420_mar171200/ext/ftp/php_ftp.c php420/ext/ftp/php_ftp.c
--- php420_mar171200/ext/ftp/php_ftp.c Thu Feb 28 09:26:10 2002
+++ php420/ext/ftp/php_ftp.c Sun Mar 17 15:14:18 2002
@@ -81,6 +81,19 @@
ZEND_GET_MODULE(php_ftp)
#endif
+static int unlink_filename(char **filename TSRMLS_DC)
+{
+ VCWD_UNLINK(*filename);
+ return 0;
+}
+
+void destroy_ftp_uploaded_files_hash(TSRMLS_D)
+{
+ zend_hash_apply(SG(ftp_uploaded_files), (apply_func_t) unlink_filename
+TSRMLS_CC);
+ zend_hash_destroy(SG(ftp_uploaded_files));
+ FREE_HASHTABLE(SG(ftp_uploaded_files));
+}
+
static void ftp_destructor_ftpbuf(zend_rsrc_list_entry *rsrc TSRMLS_DC)
{
ftpbuf_t *ftp = (ftpbuf_t *)rsrc->ptr;
@@ -413,6 +426,7 @@
FILEP(fp, z_file);
XTYPE(xtype, mode);
+
if (!ftp_get(ftp, fp, file, xtype) || ferror(fp)) {
php_error(E_WARNING, "%s(): %s", get_active_function_name(TSRMLS_C),
ftp->inbuf);
RETURN_FALSE;
@@ -468,6 +482,14 @@
ZEND_FETCH_RESOURCE(ftp, ftpbuf_t*, &z_ftp, -1, le_ftpbuf_name, le_ftpbuf);
XTYPE(xtype, mode);
+ if (PG(safe_mode) && (!php_checkuid(local, NULL,
+CHECKUID_CHECK_FILE_AND_DIR))) {
+ RETURN_FALSE;
+ }
+
+ if (php_check_open_basedir(local TSRMLS_CC)) {
+ RETURN_FALSE;
+ }
+
/* get to temporary file, so if there is an error, no existing
* file gets clobbered
*/
@@ -482,6 +504,11 @@
RETURN_FALSE;
}
+ if (!SG(ftp_uploaded_files)) {
+ ALLOC_HASHTABLE(SG(ftp_uploaded_files));
+ zend_hash_init(SG(ftp_uploaded_files), 5, NULL, (dtor_func_t)
+free_estring, 0);
+ }
+
#ifdef PHP_WIN32
if ((outfp = VCWD_FOPEN(local, "wb")) == NULL) {
#else
@@ -503,6 +530,9 @@
RETURN_FALSE;
}
+ local=estrdup(local);
+ zend_hash_add(SG(ftp_uploaded_files), local, strlen(local)+1, &local,
+sizeof(char *), NULL);
+
fclose(tmpfp);
fclose(outfp);
@@ -556,6 +586,14 @@
ZEND_FETCH_RESOURCE(ftp, ftpbuf_t*, &z_ftp, -1, le_ftpbuf_name, le_ftpbuf);
XTYPE(xtype, mode);
+
+ if (PG(safe_mode) && (!php_checkuid(local, NULL,
+CHECKUID_CHECK_FILE_AND_DIR))) {
+ RETURN_FALSE;
+ }
+
+ if (php_check_open_basedir(local TSRMLS_CC)) {
+ RETURN_FALSE;
+ }
#ifdef PHP_WIN32
if ((infp = VCWD_FOPEN(local, "rb")) == NULL) {
diff -ur php420_mar171200/ext/ftp/php_ftp.h php420/ext/ftp/php_ftp.h
--- php420_mar171200/ext/ftp/php_ftp.h Thu Feb 28 09:26:10 2002
+++ php420/ext/ftp/php_ftp.h Sun Mar 17 12:36:34 2002
@@ -58,6 +58,8 @@
#define phpext_ftp_ptr php_ftp_module_ptr
+void destroy_ftp_uploaded_files_hash(TSRMLS_D);
+
#else
#define php_ftp_module_ptr NULL
#endif /* HAVE_FTP */
diff -ur php420_mar171200/ext/standard/basic_functions.c
php420/ext/standard/basic_functions.c
--- php420_mar171200/ext/standard/basic_functions.c Fri Mar 1 04:05:49 2002
+++ php420/ext/standard/basic_functions.c Sun Mar 17 15:18:46 2002
@@ -2309,12 +2309,17 @@
}
/* {{{ proto bool is_uploaded_file(string path)
- Check if file was created by rfc1867 upload */
+ Check if file was created by rfc1867 or ftp upload */
PHP_FUNCTION(is_uploaded_file)
{
zval **path;
+#ifdef HAVE_FTP
+ if ((!SG(ftp_uploaded_files)) &&
+ (!SG(rfc1867_uploaded_files))) {
+#else /* HAVE_FTP */
if (!SG(rfc1867_uploaded_files)) {
+#endif /* HAVE_FTP */
RETURN_FALSE;
}
@@ -2324,6 +2329,11 @@
convert_to_string_ex(path);
+#ifdef HAVE_FTP
+ if (zend_hash_exists(SG(ftp_uploaded_files), Z_STRVAL_PP(path),
+Z_STRLEN_PP(path)+1)) {
+ RETURN_TRUE;
+ } else
+#endif /* HAVE_FTP */
if (zend_hash_exists(SG(rfc1867_uploaded_files), Z_STRVAL_PP(path),
Z_STRLEN_PP(path)+1)) {
RETURN_TRUE;
} else {
@@ -2338,20 +2348,31 @@
{
zval **path, **new_path;
zend_bool successful = 0;
-
+#ifdef HAVE_FTP
+ zend_bool ftpupload = 0;
+
+ if ((!SG(ftp_uploaded_files)) &&
+ (!SG(rfc1867_uploaded_files))) {
+#else /* HAVE_FTP */
if (!SG(rfc1867_uploaded_files)) {
+#endif
RETURN_FALSE;
}
-
if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &path, &new_path) !=
SUCCESS) {
ZEND_WRONG_PARAM_COUNT();
}
convert_to_string_ex(path);
convert_to_string_ex(new_path);
+#ifdef HAVE_FTP
+ if (zend_hash_exists(SG(ftp_uploaded_files), Z_STRVAL_PP(path),
+Z_STRLEN_PP(path)+1)) {
+ ftpupload = 1;
+ } else
+#else /* HAVE_FTP */
if (!zend_hash_exists(SG(rfc1867_uploaded_files), Z_STRVAL_PP(path),
Z_STRLEN_PP(path)+1)) {
RETURN_FALSE;
}
+#endif /* HAVE_FTP */
if (PG(safe_mode) && (!php_checkuid(Z_STRVAL_PP(new_path), NULL,
CHECKUID_CHECK_FILE_AND_DIR))) {
RETURN_FALSE;
@@ -2367,7 +2388,15 @@
}
if (successful) {
+#ifdef HAVE_FTP
+ if (ftpupload) {
+ zend_hash_del(SG(ftp_uploaded_files), Z_STRVAL_PP(path),
+Z_STRLEN_PP(path)+1);
+ } else {
+ zend_hash_del(SG(rfc1867_uploaded_files), Z_STRVAL_PP(path),
+Z_STRLEN_PP(path)+1);
+ }
+#else /* HAVE_FTP */
zend_hash_del(SG(rfc1867_uploaded_files), Z_STRVAL_PP(path),
Z_STRLEN_PP(path)+1);
+#endif /* HAVE_FTP */
} else {
php_error(E_WARNING, "Unable to move '%s' to '%s'", Z_STRVAL_PP(path),
Z_STRVAL_PP(new_path));
}
Only in php420_mar171200/ext/standard/tests/aggregation: aggregate.lib.php
diff -ur php420_mar171200/main/SAPI.c php420/main/SAPI.c
--- php420_mar171200/main/SAPI.c Mon Jan 14 14:36:54 2002
+++ php420/main/SAPI.c Sun Mar 17 15:15:54 2002
@@ -300,6 +300,9 @@
SG(request_info).headers_only = 0;
}
SG(rfc1867_uploaded_files) = NULL;
+#ifdef HAVE_FTP
+ SG(ftp_uploaded_files) = NULL;
+#endif /* HAVE_FTP */
if (SG(server_context)) {
if (SG(request_info).request_method
@@ -358,6 +361,11 @@
if (SG(rfc1867_uploaded_files)) {
destroy_uploaded_files_hash(TSRMLS_C);
}
+#ifdef HAVE_FTP
+ if (SG(ftp_uploaded_files)) {
+ destroy_ftp_uploaded_files_hash(TSRMLS_C);
+ }
+#endif
}
diff -ur php420_mar171200/main/SAPI.h php420/main/SAPI.h
--- php420_mar171200/main/SAPI.h Thu Feb 28 09:27:02 2002
+++ php420/main/SAPI.h Sun Mar 17 13:59:21 2002
@@ -114,6 +114,9 @@
char *default_mimetype;
char *default_charset;
HashTable *rfc1867_uploaded_files;
+#ifdef HAVE_FTP
+ HashTable *ftp_uploaded_files;
+#endif /* HAVE_FTP */
long post_max_size;
int options;
} sapi_globals_struct;
diff -ur php420_mar171200/main/safe_mode.c php420/main/safe_mode.c
--- php420_mar171200/main/safe_mode.c Thu Mar 14 20:17:23 2002
+++ php420/main/safe_mode.c Sun Mar 17 14:55:55 2002
@@ -46,7 +46,7 @@
PHPAPI int php_checkuid(const char *filename, char *fopen_mode, int mode)
{
struct stat sb;
- int ret;
+ int ret, nofile=0;
long uid=0L, gid=0L, duid=0L, dgid=0L;
char path[MAXPATHLEN];
char *s;
@@ -86,6 +86,7 @@
php_error(E_WARNING, "Unable to access %s", filename);
return 1;
}
+ nofile = 1;
} else {
uid = sb.st_uid;
gid = sb.st_gid;
@@ -140,6 +141,13 @@
return 1;
}
}
+#ifdef HAVE_FTP
+ if (SG(ftp_uploaded_files)) {
+ if (zend_hash_exists(SG(ftp_uploaded_files), (char *)
+filename, strlen(filename)+1)) {
+ return 1;
+ }
+ }
+#endif /* HAVE_FTP */
}
}
@@ -150,6 +158,13 @@
*s = 0;
}
}
+
+ if (nofile) {
+ uid = duid;
+ gid = dgid;
+ filename = path;
+ }
+
if (PG(safe_mode_gid)) {
php_error(E_WARNING, "SAFE MODE Restriction in effect. The script
whose uid/gid is %ld/%ld is not allowed to access %s owned by uid/gid %ld/%ld",
php_getuid(), php_getgid(), filename, uid, gid);
} else {
--
PHP Development Mailing List <http://www.php.net/>
To unsubscribe, visit: http://www.php.net/unsub.php