Example #1
0
static int lsapi_activate_user_ini_mk_realpath(_lsapi_activate_user_ini_ctx *ctx,
                                               void* next)
{
    char *real_path;
    int rc = SUCCESS;
    fn_activate_user_ini_chain_t *fn_next = next;

    if (!IS_ABSOLUTE_PATH(ctx->path, ctx->path_len)) {
        real_path = tsrm_realpath(ctx->path, NULL);
        if (!real_path) {
            return SUCCESS;
        }
        ctx->path = real_path;
        ctx->path_len = strlen(ctx->path);
        DEBUG_MESSAGE("calculated tsrm realpath: %s", real_path);
    } else {
        DEBUG_MESSAGE("%s is an absolute path", ctx->path);
        real_path = NULL;
    }

    if (*fn_next) {
        rc = (*fn_next)(ctx, fn_next + 1);
    }

    if (real_path)
        efree(real_path);
    return rc;
}
Example #2
0
/* {{{ zBarcodeImage zBarcodeImage::__construct([string filename, int enhance])
	Construct a new zBarcodeImage object
*/
PHP_METHOD(zbarcodeimage, __construct)
{
	php_zbarcode_image_object *intern;
	char *filename = NULL;
	int filename_len = 0;
	long enhance = 0;
	char resolved_path[MAXPATHLEN];

	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s!l", &filename, &filename_len, &enhance) == FAILURE) {
		return;
	}
	
	if (!filename) {
		return;
	}
	
	if (!tsrm_realpath(filename, resolved_path TSRMLS_CC)) {
		PHP_ZBARCODE_THROW_IMAGE_EXCEPTION(intern->magick_wand, "The file does not exist or cannot be read");
	}
	
	if (php_check_open_basedir(resolved_path TSRMLS_CC)) {
		return;
	}

	intern = (php_zbarcode_image_object *)zend_object_store_get_object(getThis() TSRMLS_CC);

	if (!_php_zbarcode_read(intern->magick_wand, resolved_path, enhance)) {
		PHP_ZBARCODE_THROW_IMAGE_EXCEPTION(intern->magick_wand, "Unable to read the image");
	}
	return;
}
Example #3
0
/* {{{ php_resolve_path
 * Returns the realpath for given filename according to include path
 */
PHPAPI zend_string *php_resolve_path(const char *filename, int filename_length, const char *path)
{
	char resolved_path[MAXPATHLEN];
	char trypath[MAXPATHLEN];
	const char *ptr, *end, *p;
	const char *actual_path;
	php_stream_wrapper *wrapper;
	zend_string *exec_filename;

	if (!filename || CHECK_NULL_PATH(filename, filename_length)) {
		return NULL;
	}

	/* Don't resolve paths which contain protocol (except of file://) */
	for (p = filename; isalnum((int)*p) || *p == '+' || *p == '-' || *p == '.'; p++);
	if ((*p == ':') && (p - filename > 1) && (p[1] == '/') && (p[2] == '/')) {
		wrapper = php_stream_locate_url_wrapper(filename, &actual_path, STREAM_OPEN_FOR_INCLUDE);
		if (wrapper == &php_plain_files_wrapper) {
			if (tsrm_realpath(actual_path, resolved_path)) {
				return zend_string_init(resolved_path, strlen(resolved_path), 0);
			}
		}
		return NULL;
	}

	if ((*filename == '.' &&
	     (IS_SLASH(filename[1]) ||
	      ((filename[1] == '.') && IS_SLASH(filename[2])))) ||
	    IS_ABSOLUTE_PATH(filename, filename_length) ||
	    !path ||
	    !*path) {
		if (tsrm_realpath(filename, resolved_path)) {
			return zend_string_init(resolved_path, strlen(resolved_path), 0);
		} else {
			return NULL;
		}
	}

	ptr = path;
	while (ptr && *ptr) {
		/* Check for stream wrapper */
		int is_stream_wrapper = 0;

		for (p = ptr; isalnum((int)*p) || *p == '+' || *p == '-' || *p == '.'; p++);
		if ((*p == ':') && (p - ptr > 1) && (p[1] == '/') && (p[2] == '/')) {
			/* .:// or ..:// is not a stream wrapper */
			if (p[-1] != '.' || p[-2] != '.' || p - 2 != ptr) {
				p += 3;
				is_stream_wrapper = 1;
			}
		}
		end = strchr(p, DEFAULT_DIR_SEPARATOR);
		if (end) {
			if ((end-ptr) + 1 + filename_length + 1 >= MAXPATHLEN) {
				ptr = end + 1;
				continue;
			}
			memcpy(trypath, ptr, end-ptr);
			trypath[end-ptr] = '/';
			memcpy(trypath+(end-ptr)+1, filename, filename_length+1);
			ptr = end+1;
		} else {
			int len = (int)strlen(ptr);

			if (len + 1 + filename_length + 1 >= MAXPATHLEN) {
				break;
			}
			memcpy(trypath, ptr, len);
			trypath[len] = '/';
			memcpy(trypath+len+1, filename, filename_length+1);
			ptr = NULL;
		}
		actual_path = trypath;
		if (is_stream_wrapper) {
			wrapper = php_stream_locate_url_wrapper(trypath, &actual_path, STREAM_OPEN_FOR_INCLUDE);
			if (!wrapper) {
				continue;
			} else if (wrapper != &php_plain_files_wrapper) {
				if (wrapper->wops->url_stat) {
					php_stream_statbuf ssb;

					if (SUCCESS == wrapper->wops->url_stat(wrapper, trypath, 0, &ssb, NULL)) {
						return zend_string_init(trypath, strlen(trypath), 0);
					}
				}
				continue;
			}
		}
		if (tsrm_realpath(actual_path, resolved_path)) {
			return zend_string_init(resolved_path, strlen(resolved_path), 0);
		}
	} /* end provided path */

	/* check in calling scripts' current working directory as a fall back case
	 */
	if (zend_is_executing() &&
	    (exec_filename = zend_get_executed_filename_ex()) != NULL) {
		const char *exec_fname = exec_filename->val;
		size_t exec_fname_length = exec_filename->len;

		while ((--exec_fname_length >= 0) && !IS_SLASH(exec_fname[exec_fname_length]));
		if (exec_fname_length > 0 &&
		    exec_fname_length + 1 + filename_length + 1 < MAXPATHLEN) {
			memcpy(trypath, exec_fname, exec_fname_length + 1);
			memcpy(trypath+exec_fname_length + 1, filename, filename_length+1);
			actual_path = trypath;

			/* Check for stream wrapper */
			for (p = trypath; isalnum((int)*p) || *p == '+' || *p == '-' || *p == '.'; p++);
			if ((*p == ':') && (p - trypath > 1) && (p[1] == '/') && (p[2] == '/')) {
				wrapper = php_stream_locate_url_wrapper(trypath, &actual_path, STREAM_OPEN_FOR_INCLUDE);
				if (!wrapper) {
					return NULL;
				} else if (wrapper != &php_plain_files_wrapper) {
					if (wrapper->wops->url_stat) {
						php_stream_statbuf ssb;

						if (SUCCESS == wrapper->wops->url_stat(wrapper, trypath, 0, &ssb, NULL)) {
							return zend_string_init(trypath, strlen(trypath), 0);
						}
					}
					return NULL;
				}
			}

			if (tsrm_realpath(actual_path, resolved_path)) {
				return zend_string_init(resolved_path, strlen(resolved_path), 0);
			}
		}
	}

	return NULL;
}
Example #4
0
TSRM_API int tsrm_win32_access(const char *pathname, int mode)
{
	time_t t;
	HANDLE thread_token = NULL;
	PSID token_sid;
	SECURITY_INFORMATION sec_info = OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION;
	GENERIC_MAPPING gen_map = { FILE_GENERIC_READ, FILE_GENERIC_WRITE, FILE_GENERIC_EXECUTE, FILE_ALL_ACCESS };
	DWORD priv_set_length = sizeof(PRIVILEGE_SET);

	PRIVILEGE_SET privilege_set = {0};
	DWORD sec_desc_length = 0, desired_access = 0, granted_access = 0;
	BYTE * psec_desc = NULL;
	BOOL fAccess = FALSE;

	realpath_cache_bucket * bucket = NULL;
	char * real_path = NULL;

	if (mode == 1 /*X_OK*/) {
		DWORD type;
		return GetBinaryType(pathname, &type) ? 0 : -1;
	} else {
		if(!IS_ABSOLUTE_PATH(pathname, strlen(pathname)+1)) {
			real_path = (char *)malloc(MAX_PATH);
			if(tsrm_realpath(pathname, real_path) == NULL) {
				goto Finished;
			}
			pathname = real_path;
 		}

		if(access(pathname, mode)) {
			free(real_path);
			return errno;
		}

 		/* If only existence check is made, return now */
 		if (mode == 0) {
			free(real_path);
			return 0;
		}

/* Only in NTS when impersonate==1 (aka FastCGI) */

		/*
		 AccessCheck() requires an impersonation token.  We first get a primary
		 token and then create a duplicate impersonation token.  The
		 impersonation token is not actually assigned to the thread, but is
		 used in the call to AccessCheck.  Thus, this function itself never
		 impersonates, but does use the identity of the thread.  If the thread
		 was impersonating already, this function uses that impersonation context.
		*/
		if(!OpenThreadToken(GetCurrentThread(), TOKEN_ALL_ACCESS, TRUE, &thread_token)) {
			if (GetLastError() == ERROR_NO_TOKEN) {
				if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &thread_token)) {
					 TWG(impersonation_token) = NULL;
					 goto Finished;
				 }
			}
		}

		/* token_sid will be freed in tsrmwin32_dtor */
		token_sid = tsrm_win32_get_token_sid(thread_token);
		if (!token_sid) {
			if (TWG(impersonation_token_sid)) {
				free(TWG(impersonation_token_sid));
			}
			TWG(impersonation_token_sid) = NULL;
			goto Finished;
		}

		/* Different identity, we need a new impersontated token as well */
		if (!TWG(impersonation_token_sid) || !EqualSid(token_sid, TWG(impersonation_token_sid))) {
			if (TWG(impersonation_token_sid)) {
				free(TWG(impersonation_token_sid));
			}
			TWG(impersonation_token_sid) = token_sid;

			/* Duplicate the token as impersonated token */
			if (!DuplicateToken(thread_token, SecurityImpersonation, &TWG(impersonation_token))) {
				goto Finished;
			}
		} else {
			/* we already have it, free it then */
			free(token_sid);
		}

		if (CWDG(realpath_cache_size_limit)) {
			t = time(0);
			bucket = realpath_cache_lookup(pathname, (int)strlen(pathname), t);
			if(bucket == NULL && real_path == NULL) {
				/* We used the pathname directly. Call tsrm_realpath */
				/* so that entry is created in realpath cache */
				real_path = (char *)malloc(MAX_PATH);
				if(tsrm_realpath(pathname, real_path) != NULL) {
					pathname = real_path;
					bucket = realpath_cache_lookup(pathname, (int)strlen(pathname), t);
				}
			}
 		}

 		/* Do a full access check because access() will only check read-only attribute */
 		if(mode == 0 || mode > 6) {
			if(bucket != NULL && bucket->is_rvalid) {
				fAccess = bucket->is_readable;
				goto Finished;
			}
 			desired_access = FILE_GENERIC_READ;
 		} else if(mode <= 2) {
			if(bucket != NULL && bucket->is_wvalid) {
				fAccess = bucket->is_writable;
				goto Finished;
			}
			desired_access = FILE_GENERIC_WRITE;
 		} else if(mode <= 4) {
			if(bucket != NULL && bucket->is_rvalid) {
				fAccess = bucket->is_readable;
				goto Finished;
			}
			desired_access = FILE_GENERIC_READ|FILE_FLAG_BACKUP_SEMANTICS;
 		} else { // if(mode <= 6)
			if(bucket != NULL && bucket->is_rvalid && bucket->is_wvalid) {
				fAccess = bucket->is_readable & bucket->is_writable;
				goto Finished;
			}
			desired_access = FILE_GENERIC_READ | FILE_GENERIC_WRITE;
 		}

		if(TWG(impersonation_token) == NULL) {
			goto Finished;
		}

		/* Get size of security buffer. Call is expected to fail */
		if(GetFileSecurity(pathname, sec_info, NULL, 0, &sec_desc_length)) {
			goto Finished;
		}

		psec_desc = (BYTE *)malloc(sec_desc_length);
		if(psec_desc == NULL ||
			 !GetFileSecurity(pathname, sec_info, (PSECURITY_DESCRIPTOR)psec_desc, sec_desc_length, &sec_desc_length)) {
			goto Finished;
		}

		MapGenericMask(&desired_access, &gen_map);

		if(!AccessCheck((PSECURITY_DESCRIPTOR)psec_desc, TWG(impersonation_token), desired_access, &gen_map, &privilege_set, &priv_set_length, &granted_access, &fAccess)) {
			goto Finished_Impersonate;
		}

		/* Keep the result in realpath_cache */
		if(bucket != NULL) {
			if(desired_access == (FILE_GENERIC_READ|FILE_FLAG_BACKUP_SEMANTICS)) {
				bucket->is_rvalid = 1;
				bucket->is_readable = fAccess;
			}
			else if(desired_access == FILE_GENERIC_WRITE) {
				bucket->is_wvalid = 1;
				bucket->is_writable = fAccess;
			} else if (desired_access == (FILE_GENERIC_READ | FILE_GENERIC_WRITE)) {
				bucket->is_rvalid = 1;
				bucket->is_readable = fAccess;
				bucket->is_wvalid = 1;
				bucket->is_writable = fAccess;
			}
		}

Finished_Impersonate:
		if(psec_desc != NULL) {
			free(psec_desc);
			psec_desc = NULL;
		}

Finished:
		if(thread_token != NULL) {
			CloseHandle(thread_token);
		}
		if(real_path != NULL) {
			free(real_path);
			real_path = NULL;
		}

		if(fAccess == FALSE) {
			errno = EACCES;
			return errno;
		} else {
			return 0;
		}
	}
}
Example #5
0
/* {{{ php_resolve_path
 * Returns the realpath for given filename according to include path
 */
PHPAPI zend_string *php_resolve_path(const char *filename, int filename_length, const char *path)
{
	char resolved_path[MAXPATHLEN];
	char trypath[MAXPATHLEN];
	const char *ptr, *end, *p;
	const char *actual_path;
	php_stream_wrapper *wrapper;
	zend_string *exec_filename;

	if (!filename || CHECK_NULL_PATH(filename, filename_length)) {
		return NULL;
	}

	/* Don't resolve paths which contain protocol (except of file://) */
	for (p = filename; isalnum((int)*p) || *p == '+' || *p == '-' || *p == '.'; p++);
	if ((*p == ':') && (p - filename > 1) && (p[1] == '/') && (p[2] == '/')) {
		wrapper = php_stream_locate_url_wrapper(filename, &actual_path, STREAM_OPEN_FOR_INCLUDE);
		if (wrapper == &php_plain_files_wrapper) {
			if (tsrm_realpath(actual_path, resolved_path)) {
				return zend_string_init(resolved_path, strlen(resolved_path), 0);
			}
		}
		return NULL;
	}

	if ((*filename == '.' &&
	     (IS_SLASH(filename[1]) ||
	      ((filename[1] == '.') && IS_SLASH(filename[2])))) ||
	    IS_ABSOLUTE_PATH(filename, filename_length) ||
#if PHP_WIN32
		/* This should count as an absolute local path as well, however
		   IS_ABSOLUTE_PATH doesn't care about this path form till now. It
		   might be a big thing to extend, thus just a local handling for
		   now. */
		filename_length >=2 && IS_SLASH(filename[0]) && !IS_SLASH(filename[1]) ||
#endif
	    !path ||
	    !*path) {
		if (tsrm_realpath(filename, resolved_path)) {
			return zend_string_init(resolved_path, strlen(resolved_path), 0);
		} else {
			return NULL;
		}
	}

	ptr = path;
	while (ptr && *ptr) {
		/* Check for stream wrapper */
		int is_stream_wrapper = 0;

		for (p = ptr; isalnum((int)*p) || *p == '+' || *p == '-' || *p == '.'; p++);
		if ((*p == ':') && (p - ptr > 1) && (p[1] == '/') && (p[2] == '/')) {
			/* .:// or ..:// is not a stream wrapper */
			if (p[-1] != '.' || p[-2] != '.' || p - 2 != ptr) {
				p += 3;
				is_stream_wrapper = 1;
			}
		}
		end = strchr(p, DEFAULT_DIR_SEPARATOR);
		if (end) {
			if (filename_length > (MAXPATHLEN - 2) || (end-ptr) > MAXPATHLEN || (end-ptr) + 1 + (size_t)filename_length + 1 >= MAXPATHLEN) {
				ptr = end + 1;
				continue;
			}
			memcpy(trypath, ptr, end-ptr);
			trypath[end-ptr] = '/';
			memcpy(trypath+(end-ptr)+1, filename, filename_length+1);
			ptr = end+1;
		} else {
			size_t len = strlen(ptr);

			if (filename_length > (MAXPATHLEN - 2) || len > MAXPATHLEN || len + 1 + (size_t)filename_length + 1 >= MAXPATHLEN) {
				break;
			}
			memcpy(trypath, ptr, len);
			trypath[len] = '/';
			memcpy(trypath+len+1, filename, filename_length+1);
			ptr = NULL;
		}
		actual_path = trypath;
		if (is_stream_wrapper) {
			wrapper = php_stream_locate_url_wrapper(trypath, &actual_path, STREAM_OPEN_FOR_INCLUDE);
			if (!wrapper) {
				continue;
			} else if (wrapper != &php_plain_files_wrapper) {
				if (wrapper->wops->url_stat) {
					php_stream_statbuf ssb;

					if (SUCCESS == wrapper->wops->url_stat(wrapper, trypath, 0, &ssb, NULL)) {
						return zend_string_init(trypath, strlen(trypath), 0);
					}
				}
				continue;
			}
		}
		if (tsrm_realpath(actual_path, resolved_path)) {
			return zend_string_init(resolved_path, strlen(resolved_path), 0);
		}
	} /* end provided path */

	/* check in calling scripts' current working directory as a fall back case
	 */
	if (zend_is_executing() &&
	    (exec_filename = zend_get_executed_filename_ex()) != NULL) {
		const char *exec_fname = ZSTR_VAL(exec_filename);
		size_t exec_fname_length = ZSTR_LEN(exec_filename);

		while ((--exec_fname_length < SIZE_MAX) && !IS_SLASH(exec_fname[exec_fname_length]));
		if (exec_fname_length > 0 &&
			filename_length < (MAXPATHLEN - 2) &&
		    exec_fname_length + 1 + filename_length + 1 < MAXPATHLEN) {
			memcpy(trypath, exec_fname, exec_fname_length + 1);
			memcpy(trypath+exec_fname_length + 1, filename, filename_length+1);
			actual_path = trypath;

			/* Check for stream wrapper */
			for (p = trypath; isalnum((int)*p) || *p == '+' || *p == '-' || *p == '.'; p++);
			if ((*p == ':') && (p - trypath > 1) && (p[1] == '/') && (p[2] == '/')) {
				wrapper = php_stream_locate_url_wrapper(trypath, &actual_path, STREAM_OPEN_FOR_INCLUDE);
				if (!wrapper) {
					return NULL;
				} else if (wrapper != &php_plain_files_wrapper) {
					if (wrapper->wops->url_stat) {
						php_stream_statbuf ssb;

						if (SUCCESS == wrapper->wops->url_stat(wrapper, trypath, 0, &ssb, NULL)) {
							return zend_string_init(trypath, strlen(trypath), 0);
						}
					}
					return NULL;
				}
			}

			if (tsrm_realpath(actual_path, resolved_path)) {
				return zend_string_init(resolved_path, strlen(resolved_path), 0);
			}
		}
	}

	return NULL;
}