Bug #2249 Updated: php.ini / user_dir doesn't work
| From: | Bug Database | Date: | Tue, 07 Sep 1999 16:53:33 +0000 |
| Subject: | Bug #2249 Updated: php.ini / user_dir doesn't work | ||
| Groups: | php.dev | ||
| Request: | Send a blank email to php-dev+get-10670@lists.php.net to get a copy of this message | ||
ID: 2249
User Update by: schmidt4@rz.uni-greifswald.de
Status: Open
Bug Type: Misbehaving function
Description: php.ini / user_dir doesn't work
I've took a look at the PHP source, exactly at php3_fopen_for_parser in fopen-wrappers.c and
modified it a little bit to
work like the UserDir directive in Apache. I'm not sure if this is really safe, but it works
fine on my server. Perhaps it
(or a rewritten function) will be implemented in a future release ?
FILE *php3_fopen_for_parser(void)
{
FILE *fp;
struct stat st;
char *temp, *path_info, *fn;
int l;
TLS_VARS;
fn = GLOBAL(request_info).filename;
path_info = GLOBAL(request_info).path_info;
#if HAVE_PWD_H
if (php3_ini.user_dir && *php3_ini.user_dir
&& path_info && '/' == path_info[0] && '~' ==
path_info[1]) {
char user[32];
struct passwd *pw;
char *s = strchr(path_info + 2, '/');
fn = NULL; /* discard the original filename, it must not be used */
if (s) { /* if there is no path name after the file, do not bother
to try open the directory */
l = s - (path_info + 2);
if (l > sizeof(user) - 1)
l = sizeof(user) - 1;
memcpy(user, path_info + 2, l);
user[l] = '\0';
#if WIN32 // new part for path creation like in Apache
fn = emalloc(strlen(php3_ini.user_dir) + strlen(path_info) + 32 + 4);
if (fn) {
strcpy(fn, php3_ini.user_dir); /* safe */
strcat(fn, "/"); /* safe */
strcat(fn, user); /* safe */
strcat(fn, "/"); /* safe */
strcat(fn, s + 1); /* safe (shorter than path_info) */
STR_FREE(GLOBAL(request_info).filename);
GLOBAL(request_info).filename = fn;
}
#else
pw = getpwnam(user);
if (pw && pw->pw_dir) {
fn = emalloc(strlen(php3_ini.user_dir) + strlen(path_info) + strlen(pw->pw_dir) + 4);
if (fn) {
strcpy(fn, pw->pw_dir); /* safe */
strcat(fn, "/"); /* safe */
strcat(fn, php3_ini.user_dir); /* safe */
strcat(fn, "/"); /* safe */
strcat(fn, s + 1); /* safe (shorter than path_info) */
STR_FREE(GLOBAL(request_info).filename);
GLOBAL(request_info).filename = fn;
}
}
#endif
}
} else
#endif
#if WIN32
if (php3_ini.doc_root && path_info && ('/' == *php3_ini.doc_root ||
'\\' == *php3_ini.doc_root || strstr(php3_ini.doc_root,":\\") ||
strstr(php3_ini.doc_root,":/"))) {
#else
if (php3_ini.doc_root && '/' == *php3_ini.doc_root && path_info) {
#endif
l = strlen(php3_ini.doc_root);
fn = emalloc(l + strlen(path_info) + 2);
if (fn) {
memcpy(fn, php3_ini.doc_root, l);
if ('/' != fn[l - 1] || '\\' != fn[l - 1]) /* l is never 0 */
fn[l++] = '/';
if ('/' == path_info[0])
l--;
strcpy(fn + l, path_info);
STR_FREE(GLOBAL(request_info).filename);
GLOBAL(request_info).filename = fn;
}
} /* if doc_root && path_info */
if (!fn) {
/* we have to free request_info.filename 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(GLOBAL(request_info).filename);
GLOBAL(request_info).filename = NULL;
return NULL;
}
fp = fopen(fn, "r");
/* refuse to open anything that is not a regular file */
if (fp && (0 > fstat(fileno(fp), &st) || !S_ISREG(st.st_mode))) {
fclose(fp);
fp = NULL;
}
if (!fp) {
php3_error(E_ERROR, "Unable to open %s", fn);
STR_FREE(GLOBAL(request_info).filename); /* for same reason as above */
return NULL;
}
_php3_hash_index_update(&GLOBAL(include_names), 0, (void *) &fn, sizeof(char *), NULL);
temp = strdup(fn);
_php3_dirname(temp, strlen(temp));
if (*temp)
chdir(temp);
free(temp);
return fp;
}
Full Bug description available at: http://bugs.php.net/?id=2249