static PHP_INI_MH(OnUpdateLog) { /* If TSRM is enabled then the last thread to update this wins */ uv_rwlock_wrlock(&log_lock); if (log_location) { free(log_location); log_location = NULL; } if (new_value) { if (PHP5TO7_STRCMP(new_value, "syslog") != 0) { char realpath[MAXPATHLEN + 1]; if (VCWD_REALPATH(PHP5TO7_STRVAL(new_value), realpath)) { log_location = strdup(realpath); } else { log_location = strdup(PHP5TO7_STRVAL(new_value)); } } else { log_location = strdup(PHP5TO7_STRVAL(new_value)); } } uv_rwlock_wrunlock(&log_lock); return SUCCESS; }
DIR *opendir(const char *dir) { DIR *dp; wchar_t *filespecw, *resolvedw; HANDLE handle; int index; char resolved_path_buff[MAXPATHLEN]; size_t resolvedw_len, filespecw_len; if (!VCWD_REALPATH(dir, resolved_path_buff)) { return NULL; } dp = (DIR *) calloc(1, sizeof(DIR)); if (dp == NULL) { return NULL; } resolvedw = php_win32_ioutil_conv_any_to_w(resolved_path_buff, PHP_WIN32_CP_IGNORE_LEN, &resolvedw_len); if (!resolvedw) { free(dp); return NULL; } filespecw_len = resolvedw_len + 2; filespecw = (wchar_t *)malloc((filespecw_len + 1)*sizeof(wchar_t)); if (filespecw == NULL) { free(dp); free(resolvedw); return NULL; } wcscpy(filespecw, resolvedw); index = (int)filespecw_len - 1; if (index >= 0 && filespecw[index] == L'/' || index == 0 && filespecw[index] == L'\\') filespecw[index] = L'\0'; wcscat(filespecw, L"\\*"); if ((handle = FindFirstFileW(filespecw, &(dp->fileinfo))) == INVALID_HANDLE_VALUE) { DWORD err = GetLastError(); if (err == ERROR_NO_MORE_FILES || err == ERROR_FILE_NOT_FOUND) { dp->finished = 1; } else { free(dp); free(filespecw); free(resolvedw); return NULL; } } dp->dirw = _wcsdup(resolvedw); dp->handle = handle; dp->offset = 0; dp->finished = 0; free(filespecw); free(resolvedw); return dp; }
DIR *opendir(const char *dir) { DIR *dp; char *filespec; HANDLE handle; int index; char resolved_path_buff[MAXPATHLEN]; TSRMLS_FETCH(); if (!VCWD_REALPATH(dir, resolved_path_buff)) { return NULL; } filespec = (char *)malloc(strlen(resolved_path_buff) + 2 + 1); if (filespec == NULL) { return NULL; } strcpy(filespec, resolved_path_buff); index = (int)strlen(filespec) - 1; if (index >= 0 && (filespec[index] == '/' || (filespec[index] == '\\' && (index == 0 || !IsDBCSLeadByte(filespec[index-1]))))) filespec[index] = '\0'; strcat(filespec, "\\*"); dp = (DIR *) malloc(sizeof(DIR)); if (dp == NULL) { free(filespec); return NULL; } dp->offset = 0; dp->finished = 0; if ((handle = FindFirstFile(filespec, &(dp->fileinfo))) == INVALID_HANDLE_VALUE) { DWORD err = GetLastError(); if (err == ERROR_NO_MORE_FILES || err == ERROR_FILE_NOT_FOUND) { dp->finished = 1; } else { free(dp); free(filespec); return NULL; } } dp->dir = strdup(resolved_path_buff); dp->handle = handle; free(filespec); return dp; }
/* _xmlreader_get_valid_file_path and _xmlreader_get_relaxNG should be made a common function in libxml extension as code is common to a few xml extensions */ char *_xmlreader_get_valid_file_path(char *source, char *resolved_path, int resolved_path_len ) { xmlURI *uri; xmlChar *escsource; char *file_dest; int isFileUri = 0; uri = xmlCreateURI(); escsource = xmlURIEscapeStr((xmlChar *)source, (xmlChar *)":"); xmlParseURIReference(uri, (const char *)escsource); xmlFree(escsource); if (uri->scheme != NULL) { /* absolute file uris - libxml only supports localhost or empty host */ if (strncasecmp(source, "file:///",8) == 0) { isFileUri = 1; #ifdef PHP_WIN32 source += 8; #else source += 7; #endif } else if (strncasecmp(source, "file://localhost/",17) == 0) { isFileUri = 1; #ifdef PHP_WIN32 source += 17; #else source += 16; #endif } } file_dest = source; if ((uri->scheme == NULL || isFileUri)) { if (!VCWD_REALPATH(source, resolved_path) && !expand_filepath(source, resolved_path)) { xmlFreeURI(uri); return NULL; } file_dest = resolved_path; } xmlFreeURI(uri); return file_dest; }
static int do_cli(int argc, char **argv) /* {{{ */ { int c; zend_file_handle file_handle; int behavior = PHP_MODE_STANDARD; char *reflection_what = NULL; volatile int request_started = 0; volatile int exit_status = 0; char *php_optarg = NULL, *orig_optarg = NULL; int php_optind = 1, orig_optind = 1; char *exec_direct=NULL, *exec_run=NULL, *exec_begin=NULL, *exec_end=NULL; char *arg_free=NULL, **arg_excp=&arg_free; char *script_file=NULL, *translated_path = NULL; int interactive=0; int lineno = 0; const char *param_error=NULL; int hide_argv = 0; zend_try { CG(in_compilation) = 0; /* not initialized but needed for several options */ while ((c = php_getopt(argc, argv, OPTIONS, &php_optarg, &php_optind, 0, 2)) != -1) { switch (c) { case 'i': /* php info & quit */ if (php_request_startup()==FAILURE) { goto err; } request_started = 1; php_print_info(0xFFFFFFFF); php_output_end_all(); exit_status = (c == '?' && argc > 1 && !strchr(argv[1], c)); goto out; case 'v': /* show php version & quit */ php_printf("PHP %s (%s) (built: %s %s) ( %s)\nCopyright (c) 1997-2016 The PHP Group\n%s", PHP_VERSION, cli_sapi_module.name, __DATE__, __TIME__, #if ZTS "ZTS " #else "NTS " #endif #if ZEND_DEBUG "DEBUG " #endif #ifdef HAVE_GCOV "GCOV " #endif , get_zend_version() ); sapi_deactivate(); goto out; case 'm': /* list compiled in modules */ if (php_request_startup()==FAILURE) { goto err; } request_started = 1; php_printf("[PHP Modules]\n"); print_modules(); php_printf("\n[Zend Modules]\n"); print_extensions(); php_printf("\n"); php_output_end_all(); exit_status=0; goto out; default: break; } } /* Set some CLI defaults */ SG(options) |= SAPI_OPTION_NO_CHDIR; php_optind = orig_optind; php_optarg = orig_optarg; while ((c = php_getopt(argc, argv, OPTIONS, &php_optarg, &php_optind, 0, 2)) != -1) { switch (c) { case 'a': /* interactive mode */ if (!interactive) { if (behavior != PHP_MODE_STANDARD) { param_error = param_mode_conflict; break; } interactive=1; } break; case 'C': /* don't chdir to the script directory */ /* This is default so NOP */ break; case 'F': if (behavior == PHP_MODE_PROCESS_STDIN) { if (exec_run || script_file) { param_error = "You can use -R or -F only once.\n"; break; } } else if (behavior != PHP_MODE_STANDARD) { param_error = param_mode_conflict; break; } behavior=PHP_MODE_PROCESS_STDIN; script_file = php_optarg; break; case 'f': /* parse file */ if (behavior == PHP_MODE_CLI_DIRECT || behavior == PHP_MODE_PROCESS_STDIN) { param_error = param_mode_conflict; break; } else if (script_file) { param_error = "You can use -f only once.\n"; break; } script_file = php_optarg; break; case 'l': /* syntax check mode */ if (behavior != PHP_MODE_STANDARD) { break; } behavior=PHP_MODE_LINT; break; case 'q': /* do not generate HTTP headers */ /* This is default so NOP */ break; case 'r': /* run code from command line */ if (behavior == PHP_MODE_CLI_DIRECT) { if (exec_direct || script_file) { param_error = "You can use -r only once.\n"; break; } } else if (behavior != PHP_MODE_STANDARD || interactive) { param_error = param_mode_conflict; break; } behavior=PHP_MODE_CLI_DIRECT; exec_direct=php_optarg; break; case 'R': if (behavior == PHP_MODE_PROCESS_STDIN) { if (exec_run || script_file) { param_error = "You can use -R or -F only once.\n"; break; } } else if (behavior != PHP_MODE_STANDARD) { param_error = param_mode_conflict; break; } behavior=PHP_MODE_PROCESS_STDIN; exec_run=php_optarg; break; case 'B': if (behavior == PHP_MODE_PROCESS_STDIN) { if (exec_begin) { param_error = "You can use -B only once.\n"; break; } } else if (behavior != PHP_MODE_STANDARD || interactive) { param_error = param_mode_conflict; break; } behavior=PHP_MODE_PROCESS_STDIN; exec_begin=php_optarg; break; case 'E': if (behavior == PHP_MODE_PROCESS_STDIN) { if (exec_end) { param_error = "You can use -E only once.\n"; break; } } else if (behavior != PHP_MODE_STANDARD || interactive) { param_error = param_mode_conflict; break; } behavior=PHP_MODE_PROCESS_STDIN; exec_end=php_optarg; break; case 's': /* generate highlighted HTML from source */ if (behavior == PHP_MODE_CLI_DIRECT || behavior == PHP_MODE_PROCESS_STDIN) { param_error = "Source highlighting only works for files.\n"; break; } behavior=PHP_MODE_HIGHLIGHT; break; case 'w': if (behavior == PHP_MODE_CLI_DIRECT || behavior == PHP_MODE_PROCESS_STDIN) { param_error = "Source stripping only works for files.\n"; break; } behavior=PHP_MODE_STRIP; break; case 'z': /* load extension file */ zend_load_extension(php_optarg); break; case 'H': hide_argv = 1; break; case 10: behavior=PHP_MODE_REFLECTION_FUNCTION; reflection_what = php_optarg; break; case 11: behavior=PHP_MODE_REFLECTION_CLASS; reflection_what = php_optarg; break; case 12: behavior=PHP_MODE_REFLECTION_EXTENSION; reflection_what = php_optarg; break; case 13: behavior=PHP_MODE_REFLECTION_ZEND_EXTENSION; reflection_what = php_optarg; break; case 14: behavior=PHP_MODE_REFLECTION_EXT_INFO; reflection_what = php_optarg; break; case 15: behavior = PHP_MODE_SHOW_INI_CONFIG; break; default: break; } } if (param_error) { PUTS(param_error); exit_status=1; goto err; } if (interactive) { #if (HAVE_LIBREADLINE || HAVE_LIBEDIT) && !defined(COMPILE_DL_READLINE) printf("Interactive shell\n\n"); #else printf("Interactive mode enabled\n\n"); #endif fflush(stdout); } /* only set script_file if not set already and not in direct mode and not at end of parameter list */ if (argc > php_optind && !script_file && behavior!=PHP_MODE_CLI_DIRECT && behavior!=PHP_MODE_PROCESS_STDIN && strcmp(argv[php_optind-1],"--")) { script_file=argv[php_optind]; php_optind++; } if (script_file) { if (cli_seek_file_begin(&file_handle, script_file, &lineno) != SUCCESS) { goto err; } else { char real_path[MAXPATHLEN]; if (VCWD_REALPATH(script_file, real_path)) { translated_path = strdup(real_path); } script_filename = script_file; } } else { /* We could handle PHP_MODE_PROCESS_STDIN in a different manner */ /* here but this would make things only more complicated. And it */ /* is consitent with the way -R works where the stdin file handle*/ /* is also accessible. */ file_handle.filename = "-"; file_handle.handle.fp = stdin; } file_handle.type = ZEND_HANDLE_FP; file_handle.opened_path = NULL; file_handle.free_filename = 0; php_self = (char*)file_handle.filename; /* before registering argv to module exchange the *new* argv[0] */ /* we can achieve this without allocating more memory */ SG(request_info).argc=argc-php_optind+1; arg_excp = argv+php_optind-1; arg_free = argv[php_optind-1]; SG(request_info).path_translated = translated_path? translated_path: (char*)file_handle.filename; argv[php_optind-1] = (char*)file_handle.filename; SG(request_info).argv=argv+php_optind-1; if (php_request_startup()==FAILURE) { *arg_excp = arg_free; fclose(file_handle.handle.fp); PUTS("Could not startup.\n"); goto err; } request_started = 1; CG(start_lineno) = lineno; *arg_excp = arg_free; /* reconstuct argv */ if (hide_argv) { int i; for (i = 1; i < argc; i++) { memset(argv[i], 0, strlen(argv[i])); } } zend_is_auto_global_str(ZEND_STRL("_SERVER")); PG(during_request_startup) = 0; switch (behavior) { case PHP_MODE_STANDARD: if (strcmp(file_handle.filename, "-")) { cli_register_file_handles(); } if (interactive && cli_shell_callbacks.cli_shell_run) { exit_status = cli_shell_callbacks.cli_shell_run(); } else { php_execute_script(&file_handle); exit_status = EG(exit_status); } break; case PHP_MODE_LINT: exit_status = php_lint_script(&file_handle); if (exit_status==SUCCESS) { zend_printf("No syntax errors detected in %s\n", file_handle.filename); } else { zend_printf("Errors parsing %s\n", file_handle.filename); } break; case PHP_MODE_STRIP: if (open_file_for_scanning(&file_handle)==SUCCESS) { zend_strip(); } goto out; break; case PHP_MODE_HIGHLIGHT: { zend_syntax_highlighter_ini syntax_highlighter_ini; if (open_file_for_scanning(&file_handle)==SUCCESS) { php_get_highlight_struct(&syntax_highlighter_ini); zend_highlight(&syntax_highlighter_ini); } goto out; } break; case PHP_MODE_CLI_DIRECT: cli_register_file_handles(); if (zend_eval_string_ex(exec_direct, NULL, "Command line code", 1) == FAILURE) { exit_status=254; } break; case PHP_MODE_PROCESS_STDIN: { char *input; size_t len, index = 0; zval argn, argi; cli_register_file_handles(); if (exec_begin && zend_eval_string_ex(exec_begin, NULL, "Command line begin code", 1) == FAILURE) { exit_status=254; } while (exit_status == SUCCESS && (input=php_stream_gets(s_in_process, NULL, 0)) != NULL) { len = strlen(input); while (len > 0 && len-- && (input[len]=='\n' || input[len]=='\r')) { input[len] = '\0'; } ZVAL_STRINGL(&argn, input, len + 1); zend_hash_str_update(&EG(symbol_table), "argn", sizeof("argn")-1, &argn); ZVAL_LONG(&argi, ++index); zend_hash_str_update(&EG(symbol_table), "argi", sizeof("argi")-1, &argi); if (exec_run) { if (zend_eval_string_ex(exec_run, NULL, "Command line run code", 1) == FAILURE) { exit_status=254; } } else { if (script_file) { if (cli_seek_file_begin(&file_handle, script_file, &lineno) != SUCCESS) { exit_status = 1; } else { CG(start_lineno) = lineno; php_execute_script(&file_handle); exit_status = EG(exit_status); } } } efree(input); } if (exec_end && zend_eval_string_ex(exec_end, NULL, "Command line end code", 1) == FAILURE) { exit_status=254; } break; } case PHP_MODE_REFLECTION_FUNCTION: case PHP_MODE_REFLECTION_CLASS: case PHP_MODE_REFLECTION_EXTENSION: case PHP_MODE_REFLECTION_ZEND_EXTENSION: { zend_class_entry *pce = NULL; zval arg, ref; zend_execute_data execute_data; switch (behavior) { default: break; case PHP_MODE_REFLECTION_FUNCTION: if (strstr(reflection_what, "::")) { pce = reflection_method_ptr; } else { pce = reflection_function_ptr; } break; case PHP_MODE_REFLECTION_CLASS: pce = reflection_class_ptr; break; case PHP_MODE_REFLECTION_EXTENSION: pce = reflection_extension_ptr; break; case PHP_MODE_REFLECTION_ZEND_EXTENSION: pce = reflection_zend_extension_ptr; break; } ZVAL_STRING(&arg, reflection_what); object_init_ex(&ref, pce); memset(&execute_data, 0, sizeof(zend_execute_data)); EG(current_execute_data) = &execute_data; zend_call_method_with_1_params(&ref, pce, &pce->constructor, "__construct", NULL, &arg); if (EG(exception)) { zval tmp, *msg, rv; ZVAL_OBJ(&tmp, EG(exception)); msg = zend_read_property(zend_ce_exception, &tmp, "message", sizeof("message")-1, 0, &rv); zend_printf("Exception: %s\n", Z_STRVAL_P(msg)); zval_ptr_dtor(&tmp); EG(exception) = NULL; } else { zend_call_method_with_1_params(NULL, reflection_ptr, NULL, "export", NULL, &ref); } zval_ptr_dtor(&ref); zval_ptr_dtor(&arg); break; } case PHP_MODE_REFLECTION_EXT_INFO: { int len = (int)strlen(reflection_what); char *lcname = zend_str_tolower_dup(reflection_what, len); zend_module_entry *module; if ((module = zend_hash_str_find_ptr(&module_registry, lcname, len)) == NULL) { if (!strcmp(reflection_what, "main")) { display_ini_entries(NULL); } else { zend_printf("Extension '%s' not present.\n", reflection_what); exit_status = 1; } } else { php_info_print_module(module); } efree(lcname); break; } case PHP_MODE_SHOW_INI_CONFIG: { zend_printf("Configuration File (php.ini) Path: %s\n", PHP_CONFIG_FILE_PATH); zend_printf("Loaded Configuration File: %s\n", php_ini_opened_path ? php_ini_opened_path : "(none)"); zend_printf("Scan for additional .ini files in: %s\n", php_ini_scanned_path ? php_ini_scanned_path : "(none)"); zend_printf("Additional .ini files parsed: %s\n", php_ini_scanned_files ? php_ini_scanned_files : "(none)"); break; } } } zend_end_try(); out: if (request_started) { php_request_shutdown((void *) 0); } if (translated_path) { free(translated_path); } if (exit_status == 0) { exit_status = EG(exit_status); } return exit_status; err: sapi_deactivate(); zend_ini_deactivate(); exit_status = 1; goto out; }
/* {{{ php_check_specific_open_basedir When open_basedir is not NULL, check if the given filename is located in open_basedir. Returns -1 if error or not in the open_basedir, else 0. When open_basedir is NULL, always return 0. */ PHPAPI int php_check_specific_open_basedir(const char *basedir, const char *path) { char resolved_name[MAXPATHLEN]; char resolved_basedir[MAXPATHLEN]; char local_open_basedir[MAXPATHLEN]; char path_tmp[MAXPATHLEN]; char *path_file; int resolved_basedir_len; int resolved_name_len; int path_len; int nesting_level = 0; /* Special case basedir==".": Use script-directory */ if (strcmp(basedir, ".") || !VCWD_GETCWD(local_open_basedir, MAXPATHLEN)) { /* Else use the unmodified path */ strlcpy(local_open_basedir, basedir, sizeof(local_open_basedir)); } path_len = (int)strlen(path); if (path_len > (MAXPATHLEN - 1)) { /* empty and too long paths are invalid */ return -1; } /* normalize and expand path */ if (expand_filepath(path, resolved_name) == NULL) { return -1; } path_len = (int)strlen(resolved_name); memcpy(path_tmp, resolved_name, path_len + 1); /* safe */ while (VCWD_REALPATH(path_tmp, resolved_name) == NULL) { #if defined(PHP_WIN32) || defined(HAVE_SYMLINK) #if defined(PHP_WIN32) if (EG(windows_version_info).dwMajorVersion > 5) { #endif if (nesting_level == 0) { int ret; char buf[MAXPATHLEN]; ret = php_sys_readlink(path_tmp, buf, MAXPATHLEN - 1); if (ret < 0) { /* not a broken symlink, move along.. */ } else { /* put the real path into the path buffer */ memcpy(path_tmp, buf, ret); path_tmp[ret] = '\0'; } } #if defined(PHP_WIN32) } #endif #endif #if defined(PHP_WIN32) || defined(NETWARE) path_file = strrchr(path_tmp, DEFAULT_SLASH); if (!path_file) { path_file = strrchr(path_tmp, '/'); } #else path_file = strrchr(path_tmp, DEFAULT_SLASH); #endif if (!path_file) { /* none of the path components exist. definitely not in open_basedir.. */ return -1; } else { path_len = path_file - path_tmp + 1; #if defined(PHP_WIN32) || defined(NETWARE) if (path_len > 1 && path_tmp[path_len - 2] == ':') { if (path_len != 3) { return -1; } /* this is c:\ */ path_tmp[path_len] = '\0'; } else { path_tmp[path_len - 1] = '\0'; } #else path_tmp[path_len - 1] = '\0'; #endif } nesting_level++; } /* Resolve open_basedir to resolved_basedir */ if (expand_filepath(local_open_basedir, resolved_basedir) != NULL) { int basedir_len = (int)strlen(basedir); /* Handler for basedirs that end with a / */ resolved_basedir_len = (int)strlen(resolved_basedir); #if defined(PHP_WIN32) || defined(NETWARE) if (basedir[basedir_len - 1] == PHP_DIR_SEPARATOR || basedir[basedir_len - 1] == '/') { #else if (basedir[basedir_len - 1] == PHP_DIR_SEPARATOR) { #endif if (resolved_basedir[resolved_basedir_len - 1] != PHP_DIR_SEPARATOR) { resolved_basedir[resolved_basedir_len] = PHP_DIR_SEPARATOR; resolved_basedir[++resolved_basedir_len] = '\0'; } } else { resolved_basedir[resolved_basedir_len++] = PHP_DIR_SEPARATOR; resolved_basedir[resolved_basedir_len] = '\0'; } resolved_name_len = (int)strlen(resolved_name); if (path_tmp[path_len - 1] == PHP_DIR_SEPARATOR) { if (resolved_name[resolved_name_len - 1] != PHP_DIR_SEPARATOR) { resolved_name[resolved_name_len] = PHP_DIR_SEPARATOR; resolved_name[++resolved_name_len] = '\0'; } } /* Check the path */ #if defined(PHP_WIN32) || defined(NETWARE) if (strncasecmp(resolved_basedir, resolved_name, resolved_basedir_len) == 0) { #else if (strncmp(resolved_basedir, resolved_name, resolved_basedir_len) == 0) { #endif if (resolved_name_len > resolved_basedir_len && resolved_name[resolved_basedir_len - 1] != PHP_DIR_SEPARATOR) { return -1; } else { /* File is in the right directory */ return 0; } } else { /* /openbasedir/ and /openbasedir are the same directory */ if (resolved_basedir_len == (resolved_name_len + 1) && resolved_basedir[resolved_basedir_len - 1] == PHP_DIR_SEPARATOR) { #if defined(PHP_WIN32) || defined(NETWARE) if (strncasecmp(resolved_basedir, resolved_name, resolved_name_len) == 0) { #else if (strncmp(resolved_basedir, resolved_name, resolved_name_len) == 0) { #endif return 0; } } return -1; } } else { /* Unable to resolve the real path, return -1 */ return -1; } } /* }}} */ PHPAPI int php_check_open_basedir(const char *path) { return php_check_open_basedir_ex(path, 1); } /* {{{ php_check_open_basedir */ PHPAPI int php_check_open_basedir_ex(const char *path, int warn) { /* Only check when open_basedir is available */ if (PG(open_basedir) && *PG(open_basedir)) { char *pathbuf; char *ptr; char *end; /* Check if the path is too long so we can give a more useful error * message. */ if (strlen(path) > (MAXPATHLEN - 1)) { php_error_docref(NULL, E_WARNING, "File name is longer than the maximum allowed path length on this platform (%d): %s", MAXPATHLEN, path); errno = EINVAL; return -1; } pathbuf = estrdup(PG(open_basedir)); ptr = pathbuf; while (ptr && *ptr) { end = strchr(ptr, DEFAULT_DIR_SEPARATOR); if (end != NULL) { *end = '\0'; end++; } if (php_check_specific_open_basedir(ptr, path) == 0) { efree(pathbuf); return 0; } ptr = end; } if (warn) { php_error_docref(NULL, E_WARNING, "open_basedir restriction in effect. File(%s) is not within the allowed path(s): (%s)", path, PG(open_basedir)); } efree(pathbuf); errno = EPERM; /* we deny permission to open it */ return -1; } /* Nothing to check... */ return 0; } /* }}} */ /* {{{ php_fopen_and_set_opened_path */ static FILE *php_fopen_and_set_opened_path(const char *path, const char *mode, zend_string **opened_path) { FILE *fp; if (php_check_open_basedir((char *)path)) { return NULL; } fp = VCWD_FOPEN(path, mode); if (fp && opened_path) { //TODO :avoid reallocation char *tmp = expand_filepath_with_mode(path, NULL, NULL, 0, CWD_EXPAND); if (tmp) { *opened_path = zend_string_init(tmp, strlen(tmp), 0); efree(tmp); } } return fp; }
void zend_accel_blacklist_load(zend_blacklist *blacklist, char *filename) #endif { char buf[MAXPATHLEN + 1], real_path[MAXPATHLEN + 1], *blacklist_path = NULL; FILE *fp; int path_length, blacklist_path_length; if ((fp = fopen(filename, "r")) == NULL) { zend_accel_error(ACCEL_LOG_WARNING, "Cannot load blacklist file: %s\n", filename); return; } zend_accel_error(ACCEL_LOG_DEBUG,"Loading blacklist file: '%s'", filename); if (VCWD_REALPATH(filename, buf)) { blacklist_path_length = zend_dirname(buf, strlen(buf)); blacklist_path = zend_strndup(buf, blacklist_path_length); } memset(buf, 0, sizeof(buf)); memset(real_path, 0, sizeof(real_path)); while (fgets(buf, MAXPATHLEN, fp) != NULL) { char *path_dup, *pbuf; path_length = strlen(buf); if (path_length > 0 && buf[path_length - 1] == '\n') { buf[--path_length] = 0; if (path_length > 0 && buf[path_length - 1] == '\r') { buf[--path_length] = 0; } } /* Strip ctrl-m prefix */ pbuf = &buf[0]; while (*pbuf == '\r') { *pbuf++ = 0; path_length--; } /* strip \" */ if (pbuf[0] == '\"' && pbuf[path_length - 1]== '\"') { *pbuf++ = 0; path_length -= 2; } if (path_length == 0) { continue; } /* skip comments */ if (pbuf[0]==';') { continue; } path_dup = zend_strndup(pbuf, path_length); if (blacklist_path) { expand_filepath_ex(path_dup, real_path, blacklist_path, blacklist_path_length); } else { expand_filepath(path_dup, real_path); } path_length = strlen(real_path); free(path_dup); zend_accel_blacklist_allocate(blacklist); blacklist->entries[blacklist->pos].path_length = path_length; blacklist->entries[blacklist->pos].path = (char *)malloc(path_length + 1); if (!blacklist->entries[blacklist->pos].path) { zend_accel_error(ACCEL_LOG_ERROR, "malloc() failed\n"); fclose(fp); return; } blacklist->entries[blacklist->pos].id = blacklist->pos; memcpy(blacklist->entries[blacklist->pos].path, real_path, path_length + 1); blacklist->pos++; } fclose(fp); if (blacklist_path) { free(blacklist_path); } zend_accel_blacklist_update_regexp(blacklist); }
DIR *opendir(const char *dir) {/*{{{*/ DIR *dp; wchar_t *filespecw, *resolvedw; HANDLE handle; char resolved_path_buff[MAXPATHLEN]; size_t resolvedw_len, filespecw_len, index; zend_bool might_need_prefix; if (!VCWD_REALPATH(dir, resolved_path_buff)) { return NULL; } resolvedw = php_win32_ioutil_conv_any_to_w(resolved_path_buff, PHP_WIN32_CP_IGNORE_LEN, &resolvedw_len); if (!resolvedw) { return NULL; } might_need_prefix = resolvedw_len >= 3 && PHP_WIN32_IOUTIL_IS_LETTERW(resolvedw[0]) && L':' == resolvedw[1] && PHP_WIN32_IOUTIL_IS_SLASHW(resolvedw[2]); filespecw_len = resolvedw_len + 2; if (filespecw_len >= _MAX_PATH && might_need_prefix) { filespecw_len += PHP_WIN32_IOUTIL_LONG_PATH_PREFIX_LENW; } filespecw = (wchar_t *)malloc((filespecw_len + 1)*sizeof(wchar_t)); if (filespecw == NULL) { free(resolvedw); return NULL; } if (filespecw_len >= _MAX_PATH && might_need_prefix) { wcscpy(filespecw, PHP_WIN32_IOUTIL_LONG_PATH_PREFIXW); wcscpy(filespecw + PHP_WIN32_IOUTIL_LONG_PATH_PREFIX_LENW, resolvedw); index = resolvedw_len + PHP_WIN32_IOUTIL_LONG_PATH_PREFIX_LENW - 1; } else { wcscpy(filespecw, resolvedw); index = resolvedw_len - 1; } if (index >= 0 && filespecw[index] == L'/' || index == 0 && filespecw[index] == L'\\') filespecw[index] = L'\0'; wcscat(filespecw, L"\\*"); dp = (DIR *) calloc(1, sizeof(DIR) + (_MAX_FNAME*5+1)*sizeof(char)); if (dp == NULL) { free(resolvedw); return NULL; } if ((handle = FindFirstFileExW(filespecw, FindExInfoBasic, &(dp->fileinfo), FindExSearchNameMatch, NULL, FIND_FIRST_EX_LARGE_FETCH)) == INVALID_HANDLE_VALUE) { DWORD err = GetLastError(); if (err == ERROR_NO_MORE_FILES || err == ERROR_FILE_NOT_FOUND) { dp->finished = 1; } else { free(dp); free(filespecw); free(resolvedw); return NULL; } } dp->dirw = _wcsdup(resolvedw); dp->handle = handle; dp->offset = 0; dp->finished = 0; free(filespecw); free(resolvedw); return dp; }/*}}}*/
SSL *SSL_new_from_context(SSL_CTX *ctx, stream *stream) /* {{{ */ { zval **val = NULL; char *cafile = NULL; char *capath = NULL; char *certfile = NULL; char *cipherlist = NULL; int ok = 1; ERR_clear_error(); /* look at context options in the stream and set appropriate verification flags */ if (GET_VER_OPT("verify_peer") && zval_is_true(*val)) { /* turn on verification callback */ SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, verify_callback); /* CA stuff */ GET_VER_OPT_STRING("cafile", cafile); GET_VER_OPT_STRING("capath", capath); if (cafile || capath) { if (!SSL_CTX_load_verify_locations(ctx, cafile, capath)) { error_docref(NULL, E_WARNING, "Unable to set verify locations `%s' `%s'", cafile, capath); return NULL; } } if (GET_VER_OPT("verify_depth")) { convert_to_long_ex(val); SSL_CTX_set_verify_depth(ctx, Z_LVAL_PP(val)); } } else { SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, NULL); } /* callback for the passphrase (for localcert) */ if (GET_VER_OPT("passphrase")) { SSL_CTX_set_default_passwd_cb_userdata(ctx, stream); SSL_CTX_set_default_passwd_cb(ctx, passwd_callback); } GET_VER_OPT_STRING("ciphers", cipherlist); if (!cipherlist) { cipherlist = "DEFAULT"; } if (SSL_CTX_set_cipher_list(ctx, cipherlist) != 1) { return NULL; } GET_VER_OPT_STRING("local_cert", certfile); if (certfile) { X509 *cert = NULL; EVP_PKEY *key = NULL; SSL *tmpssl; char resolved_path_buff[MAXPATHLEN]; const char * private_key = NULL; if (VCWD_REALPATH(certfile, resolved_path_buff)) { /* a certificate to use for authentication */ if (SSL_CTX_use_certificate_chain_file(ctx, resolved_path_buff) != 1) { error_docref(NULL, E_WARNING, "Unable to set local cert chain file `%s'; Check that your cafile/capath settings include details of your certificate and its issuer", certfile); return NULL; } GET_VER_OPT_STRING("local_pk", private_key); if (private_key) { char resolved_path_buff_pk[MAXPATHLEN]; if (VCWD_REALPATH(private_key, resolved_path_buff_pk)) { if (SSL_CTX_use_PrivateKey_file(ctx, resolved_path_buff_pk, SSL_FILETYPE_PEM) != 1) { error_docref(NULL, E_WARNING, "Unable to set private key file `%s'", resolved_path_buff_pk); return NULL; } } } else { if (SSL_CTX_use_PrivateKey_file(ctx, resolved_path_buff, SSL_FILETYPE_PEM) != 1) { error_docref(NULL, E_WARNING, "Unable to set private key file `%s'", resolved_path_buff); return NULL; } } tmpssl = SSL_new(ctx); cert = SSL_get_certificate(tmpssl); if (cert) { key = X509_get_pubkey(cert); EVP_PKEY_copy_parameters(key, SSL_get_privatekey(tmpssl)); EVP_PKEY_free(key); } SSL_free(tmpssl); if (!SSL_CTX_check_private_key(ctx)) { error_docref(NULL, E_WARNING, "Private key does not match certificate!"); } } } if (ok) { SSL *ssl = SSL_new(ctx); if (ssl) { /* map SSL => stream */ SSL_set_ex_data(ssl, ssl_stream_data_index, stream); } return ssl; } return NULL; }
PHPAPI int php_checkuid_ex(const char *filename, const char *fopen_mode, int mode, int flags) { struct stat sb; int ret, nofile=0; long uid=0L, gid=0L, duid=0L, dgid=0L; char path[MAXPATHLEN]; char *s, filenamecopy[MAXPATHLEN]; TSRMLS_FETCH(); path[0] = '\0'; if (!filename) { return 0; /* path must be provided */ } if (strlcpy(filenamecopy, filename, MAXPATHLEN)>=MAXPATHLEN) { return 0; } filename=(char *)&filenamecopy; if (fopen_mode) { if (fopen_mode[0] == 'r') { mode = CHECKUID_DISALLOW_FILE_NOT_EXISTS; } else { mode = CHECKUID_CHECK_FILE_AND_DIR; } } /* First we see if the file is owned by the same user... * If that fails, passthrough and check directory... */ if (mode != CHECKUID_ALLOW_ONLY_DIR) { #if HAVE_BROKEN_GETCWD char ftest[MAXPATHLEN]; strcpy(ftest, filename); if (VCWD_GETCWD(ftest, sizeof(ftest)) == NULL) { strcpy(path, filename); } else #endif expand_filepath(filename, path TSRMLS_CC); ret = VCWD_STAT(path, &sb); if (ret < 0) { if (mode == CHECKUID_DISALLOW_FILE_NOT_EXISTS) { if ((flags & CHECKUID_NO_ERRORS) == 0) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to access %s", filename); } return 0; } else if (mode == CHECKUID_ALLOW_FILE_NOT_EXISTS) { if ((flags & CHECKUID_NO_ERRORS) == 0) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to access %s", filename); } return 1; } nofile = 1; } else { uid = sb.st_uid; gid = sb.st_gid; if (uid == php_getuid()) { return 1; } else if (PG(safe_mode_gid) && gid == php_getgid()) { return 1; } } /* Trim off filename */ if ((s = strrchr(path, DEFAULT_SLASH))) { if (*(s + 1) == '\0' && s != path) { /* make sure that the / is not the last character */ *s = '\0'; s = strrchr(path, DEFAULT_SLASH); } if (s) { if (s == path) { path[1] = '\0'; } else { *s = '\0'; } } } } else { /* CHECKUID_ALLOW_ONLY_DIR */ s = strrchr(filename, DEFAULT_SLASH); if (s == filename) { /* root dir */ path[0] = DEFAULT_SLASH; path[1] = '\0'; } else if (s && *(s + 1) != '\0') { /* make sure that the / is not the last character */ *s = '\0'; VCWD_REALPATH(filename, path); *s = DEFAULT_SLASH; } else { /* Under Solaris, getcwd() can fail if there are no * read permissions on a component of the path, even * though it has the required x permissions */ path[0] = '.'; path[1] = '\0'; VCWD_GETCWD(path, sizeof(path)); } } /* end CHECKUID_ALLOW_ONLY_DIR */ if (mode != CHECKUID_ALLOW_ONLY_FILE) { /* check directory */ ret = VCWD_STAT(path, &sb); if (ret < 0) { if ((flags & CHECKUID_NO_ERRORS) == 0) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to access %s", filename); } return 0; } duid = sb.st_uid; dgid = sb.st_gid; if (duid == php_getuid()) { return 1; } else if (PG(safe_mode_gid) && dgid == php_getgid()) { return 1; } else { if (SG(rfc1867_uploaded_files)) { if (zend_hash_exists(SG(rfc1867_uploaded_files), (char *) filename, strlen(filename)+1)) { return 1; } } } } if (mode == CHECKUID_ALLOW_ONLY_DIR) { uid = duid; gid = dgid; if (s) { *s = 0; } } if (nofile) { uid = duid; gid = dgid; filename = path; } if ((flags & CHECKUID_NO_ERRORS) == 0) { if (PG(safe_mode_gid)) { php_error_docref(NULL TSRMLS_CC, 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_error_docref(NULL TSRMLS_CC, E_WARNING, "SAFE MODE Restriction in effect. The script whose uid is %ld is not allowed to access %s owned by uid %ld", php_getuid(), filename, uid); } } return 0; }