summaryrefslogtreecommitdiff
path: root/main/fopen_wrappers.c
diff options
context:
space:
mode:
Diffstat (limited to 'main/fopen_wrappers.c')
-rw-r--r--main/fopen_wrappers.c179
1 files changed, 98 insertions, 81 deletions
diff --git a/main/fopen_wrappers.c b/main/fopen_wrappers.c
index 38d410018b..ae7b52afde 100644
--- a/main/fopen_wrappers.c
+++ b/main/fopen_wrappers.c
@@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| PHP HTML Embedded Scripting Language Version 3.0 |
+----------------------------------------------------------------------+
- | Copyright (c) 1997,1998 PHP Development Team (See Credits file) |
+ | Copyright (c) 1997-1999 PHP Development Team (See Credits file) |
+----------------------------------------------------------------------+
| This program is free software; you can redistribute it and/or modify |
| it under the terms of one of the following licenses: |
@@ -29,6 +29,8 @@
*/
/* $Id$ */
+/* Synced with php3 revision 1.62 1999-06-16 [ssb] */
+
#include "php.h"
#include "php_globals.h"
#include "SAPI.h"
@@ -98,80 +100,94 @@ int _php3_getftpresult(int socketd);
When open_basedir is NULL, always return 0
*/
-PHPAPI int _php3_check_open_basedir(char *path)
+PHPAPI int _php3_check_specific_open_basedir(char *basedir, char *path)
{
char resolved_name[MAXPATHLEN];
+ char resolved_basedir[MAXPATHLEN];
char local_open_basedir[MAXPATHLEN];
int local_open_basedir_pos;
PLS_FETCH();
- /* Only check when open_basedir is available */
- if (PG(open_basedir) && *PG(open_basedir)) {
-
- /* Special case basedir==".": Use script-directory */
- if ((strcmp(PG(open_basedir), ".") == 0) &&
- request_info.filename &&
- *request_info.filename
+ /* Special case basedir==".": Use script-directory */
+ if ((strcmp(PG(open_basedir), ".") == 0) &&
+ SG(request_info).path_translated &&
+ *SG(request_info).path_translated
) {
- strcpy(local_open_basedir, request_info.filename);
- local_open_basedir_pos = strlen(local_open_basedir) - 1;
+ strcpy(local_open_basedir, SG(request_info).path_translated);
+ local_open_basedir_pos = strlen(local_open_basedir) - 1;
- /* Strip filename */
- while ((
+ /* Strip filename */
+ while ((
#if WIN32|WINNT
- (local_open_basedir[local_open_basedir_pos] != '\\') ||
+ (local_open_basedir[local_open_basedir_pos] != '\\') ||
#endif
- (local_open_basedir[local_open_basedir_pos] != '/')
- ) &&
- (local_open_basedir_pos >= 0)
+ (local_open_basedir[local_open_basedir_pos] != '/')
+ ) &&
+ (local_open_basedir_pos >= 0)
) {
- local_open_basedir[local_open_basedir_pos--] = 0;
- }
-
-#if 0
- /* Strip double (back)slashes */
- if (local_open_basedir_pos > 0) {
- while ((
+ local_open_basedir[local_open_basedir_pos--] = 0;
+ }
+ } else {
+ /* Else use the unmodified path */
+ strcpy(local_open_basedir, basedir);
+ }
+
+ /* Resolve the real path into resolved_name */
+ if ((_php3_realpath(path, resolved_name) != NULL) && (_php3_realpath(local_open_basedir, resolved_basedir) != NULL)) {
+ /* Check the path */
#if WIN32|WINNT
- (local_open_basedir[local_open_basedir_pos-1] == '\\') ||
-#endif
- (local_open_basedir[local_open_basedir_pos-1] == '/')
- ) &&
- (local_open_basedir_pos > 0)
- ) {
- local_open_basedir[local_open_basedir_pos--] = 0;
- }
- }
+ if (strncasecmp(resolved_basedir, resolved_name, strlen(resolved_basedir)) == 0) {
+#else
+ if (strncmp(resolved_basedir, resolved_name, strlen(resolved_basedir)) == 0) {
#endif
-
+ /* File is in the right directory */
+ return 0;
} else {
- /* Else use the unmodified path */
- strcpy(local_open_basedir, PG(open_basedir));
+ return -1;
}
-
- /* Resolve the real path into resolved_name */
- if (_php3_realpath(path, resolved_name) != NULL) {
- /* Check the path */
+ } else {
+ /* Unable to resolve the real path, return -1 */
+ return -1;
+ }
+}
+
+PHPAPI int _php3_check_open_basedir(char *path)
+{
+ /* Only check when open_basedir is available */
+ if (PG(open_basedir) && *PG(open_basedir)) {
+ char *pathbuf;
+ char *ptr;
+ char *end;
+
+ pathbuf = estrdup(PG(open_basedir));
+
+ ptr = pathbuf;
+
+ while (ptr && *ptr) {
#if WIN32|WINNT
- if (strncasecmp(local_open_basedir, resolved_name, strlen(local_open_basedir)) == 0) {
+ end = strchr(ptr, ';');
#else
- if (strncmp(local_open_basedir, resolved_name, strlen(local_open_basedir)) == 0) {
+ end = strchr(ptr, ':');
#endif
- /* File is in the right directory */
+ if (end != NULL) {
+ *end = '\0';
+ end++;
+ }
+
+ if (_php3_check_specific_open_basedir(ptr, path) == 0) {
+ efree(pathbuf);
return 0;
- } else {
- php3_error(E_WARNING, "open_basedir restriction in effect. File is in wrong directory.");
- return -1;
}
- } else {
- /* Unable to resolve the real path, return -1 */
- php3_error(E_WARNING, "open_basedir restriction in effect. Unable to verify location of file.");
- return -1;
+
+ ptr = end;
}
- } else {
- /* open_basedir is not available, return 0 */
- return 0;
+ php3_error(E_WARNING, "open_basedir restriction in effect. File is in wrong directory.");
+ efree(pathbuf);
+ return -1;
}
+
+ /* Nothing to check... */
+ return 0;
}
PHPAPI FILE *php3_fopen_wrapper(char *path, char *mode, int options, int *issock, int *socketd)
@@ -179,6 +195,8 @@ PHPAPI FILE *php3_fopen_wrapper(char *path, char *mode, int options, int *issock
int cm=2; /* checkuid mode: 2 = if file does not exist, check directory */
PLS_FETCH();
+ /* FIXME Lets not get in the habit of doing stuff like this. This should
+ be runtime enabled, NOT compile time. */
#if PHP3_URL_FOPEN
if (!(options & IGNORE_URL)) {
return php3_fopen_url_wrapper(path, mode, options, issock, socketd);
@@ -208,7 +226,7 @@ PHPAPI FILE *php3_fopen_for_parser(void)
PLS_FETCH();
SLS_FETCH();
- fn = request_info.filename;
+ fn = SG(request_info).path_translated;
path_info = SG(request_info).request_uri;
#if HAVE_PWD_H
if (PG(user_dir) && *PG(user_dir)
@@ -236,8 +254,8 @@ PHPAPI FILE *php3_fopen_for_parser(void)
strcat(fn, PG(user_dir)); /* safe */
strcat(fn, "/"); /* safe */
strcat(fn, s + 1); /* safe (shorter than path_info) */
- STR_FREE(request_info.filename);
- request_info.filename = fn;
+ STR_FREE(SG(request_info).path_translated);
+ SG(request_info).path_translated = fn;
}
}
}
@@ -259,17 +277,17 @@ PHPAPI FILE *php3_fopen_for_parser(void)
if ('/' == path_info[0])
l--;
strcpy(fn + l, path_info);
- STR_FREE(request_info.filename);
- request_info.filename = fn;
+ STR_FREE(SG(request_info).path_translated);
+ SG(request_info).path_translated = fn;
}
} /* if doc_root && path_info */
if (!fn) {
- /* we have to free request_info.filename here because
+ /* we have to free SG(request_info).path_translated here because
php3_destroy_request_info assumes that it will get
freed when the include_names hash is emptied, but
we're not adding it in this case */
- STR_FREE(request_info.filename);
- request_info.filename = NULL;
+ STR_FREE(SG(request_info).path_translated);
+ SG(request_info).path_translated = NULL;
return NULL;
}
fp = fopen(fn, "r");
@@ -281,7 +299,7 @@ PHPAPI FILE *php3_fopen_for_parser(void)
}
if (!fp) {
php3_error(E_CORE_ERROR, "Unable to open %s", fn);
- STR_FREE(request_info.filename); /* for same reason as above */
+ STR_FREE(SG(request_info).path_translated); /* for same reason as above */
return NULL;
}
@@ -443,7 +461,6 @@ static FILE *php3_fopen_url_wrapper(const char *path, char *mode, int options, i
FILE *fp = NULL;
struct sockaddr_in server;
unsigned short portno;
- char winfeof;
if (!strncasecmp(path, "http://", 7)) {
resource = url_parse((char *) path);
@@ -463,16 +480,15 @@ static FILE *php3_fopen_url_wrapper(const char *path, char *mode, int options, i
free_url(resource);
return NULL;
}
- lookup_hostname(resource->host, &server.sin_addr);
+ server.sin_family = AF_INET;
- if (server.sin_addr.s_addr == -1) {
+ if (lookup_hostname(resource->host, &server.sin_addr)) {
SOCK_FCLOSE(*socketd);
*socketd = 0;
free_url(resource);
return NULL;
}
server.sin_port = htons(resource->port);
- server.sin_family = AF_INET;
if (connect(*socketd, (struct sockaddr *) &server, sizeof(server)) == SOCK_CONN_ERR) {
SOCK_FCLOSE(*socketd);
@@ -554,8 +570,8 @@ static FILE *php3_fopen_url_wrapper(const char *path, char *mode, int options, i
/* Read past http header */
body = 0;
location[0] = '\0';
- while (!body && recv(*socketd, (char *) &winfeof, 1, MSG_PEEK)) {
- if (SOCK_FGETC(buf, *socketd) == SOCK_RECV_ERR) {
+ while (!body && !SOCK_FEOF(*socketd)) {
+ if ((buf[0] = SOCK_FGETC(*socketd)) == EOF) {
SOCK_FCLOSE(*socketd);
*socketd = 0;
free_url(resource);
@@ -629,9 +645,9 @@ static FILE *php3_fopen_url_wrapper(const char *path, char *mode, int options, i
free_url(resource);
return NULL;
}
- lookup_hostname(resource->host, &server.sin_addr);
+ server.sin_family = AF_INET;
- if (server.sin_addr.s_addr == -1) {
+ if (lookup_hostname(resource->host, &server.sin_addr)) {
SOCK_FCLOSE(*socketd);
*socketd = 0;
free_url(resource);
@@ -712,6 +728,16 @@ static FILE *php3_fopen_url_wrapper(const char *path, char *mode, int options, i
return NULL;
}
+ /* set the connection to be binary */
+ SOCK_WRITE("TYPE I\n", *socketd);
+ result = _php3_getftpresult(*socketd);
+ if (result > 299 || result < 200) {
+ free_url(resource);
+ SOCK_FCLOSE(*socketd);
+ *socketd = 0;
+ return NULL;
+ }
+
/* find out the size of the file (verifying it exists) */
SOCK_WRITE("SIZE ", *socketd);
SOCK_WRITE(resource->path, *socketd);
@@ -741,15 +767,6 @@ static FILE *php3_fopen_url_wrapper(const char *path, char *mode, int options, i
}
}
- /* set the connection to be binary */
- SOCK_WRITE("TYPE I\n", *socketd);
- result = _php3_getftpresult(*socketd);
- if (result > 299 || result < 200) {
- free_url(resource);
- SOCK_FCLOSE(*socketd);
- *socketd = 0;
- return NULL;
- }
/* set up the passive connection */
SOCK_WRITE("PASV\n", *socketd);
while (SOCK_FGETS(tmp_line, 256, *socketd) &&
@@ -841,9 +858,9 @@ static FILE *php3_fopen_url_wrapper(const char *path, char *mode, int options, i
free_url(resource);
return NULL;
}
- lookup_hostname(resource->host, &server.sin_addr);
+ server.sin_family = AF_INET;
- if (server.sin_addr.s_addr == -1) {
+ if (lookup_hostname(resource->host, &server.sin_addr)) {
free_url(resource);
SOCK_FCLOSE(*socketd);
*socketd = 0;