/* {{{ Mosquitto\Client::setTlsCertificates() */ PHP_METHOD(Mosquitto_Client, setTlsCertificates) { mosquitto_client_object *object; char *ca_path = NULL, *cert_path = NULL, *key_path = NULL, *key_pw = NULL; int ca_path_len = 0, cert_path_len = 0, key_path_len = 0, key_pw_len, retval = 0; zval stat; zend_bool is_dir = 0; int (*pw_callback)(char *, int, int, void *) = NULL; PHP_MOSQUITTO_ERROR_HANDLING(); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s!|s!s!s!", &ca_path, &ca_path_len, &cert_path, &cert_path_len, &key_path, &key_path_len, &key_pw, &key_pw_len) == FAILURE) { PHP_MOSQUITTO_RESTORE_ERRORS(); return; } if ((php_check_open_basedir(ca_path TSRMLS_CC) < 0) || (php_check_open_basedir(cert_path TSRMLS_CC) < 0) || (php_check_open_basedir(key_path TSRMLS_CC) < 0)) { PHP_MOSQUITTO_RESTORE_ERRORS(); return; } PHP_MOSQUITTO_RESTORE_ERRORS(); object = (mosquitto_client_object *) zend_object_store_get_object(getThis() TSRMLS_CC); php_stat(ca_path, ca_path_len, FS_IS_DIR, &stat TSRMLS_CC); is_dir = Z_BVAL(stat); if (key_pw != NULL) { pw_callback = php_mosquitto_pw_callback; MQTTG(client_key) = estrdup(key_pw); MQTTG(client_key_len) = key_pw_len; } if (is_dir) { retval = mosquitto_tls_set(object->client, NULL, ca_path, cert_path, key_path, pw_callback); } else { retval = mosquitto_tls_set(object->client, ca_path, NULL, cert_path, key_path, pw_callback); } php_mosquitto_handle_errno(retval, errno TSRMLS_CC); RETURN_LONG(retval); }
/* {{{ 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; }
static char *make_filename_safe(const char *filename) { if (*filename && memcmp(filename, ":memory:", sizeof(":memory:"))) { char *fullpath = expand_filepath(filename, NULL); if (!fullpath) { return NULL; } if (php_check_open_basedir(fullpath)) { efree(fullpath); return NULL; } return fullpath; } return estrdup(filename); }
static void pspell_config_path(INTERNAL_FUNCTION_PARAMETERS, char *option) { zend_long conf; char *value; size_t value_len; PspellConfig *config; if (zend_parse_parameters(ZEND_NUM_ARGS(), "lp", &conf, &value, &value_len) == FAILURE) { return; } PSPELL_FETCH_CONFIG; if (php_check_open_basedir(value)) { RETURN_FALSE; } pspell_config_replace(config, option, value); RETURN_TRUE; }
/* {{{ proto bool pspell_config_repl(int conf, string repl) Use a personal dictionary with replacement pairs for this config */ static PHP_FUNCTION(pspell_config_repl) { zend_long conf; char *repl; size_t repl_len; PspellConfig *config; if (zend_parse_parameters(ZEND_NUM_ARGS(), "lp", &conf, &repl, &repl_len) == FAILURE) { return; } PSPELL_FETCH_CONFIG; pspell_config_replace(config, "save-repl", "true"); if (php_check_open_basedir(repl)) { RETURN_FALSE; } pspell_config_replace(config, "repl", repl); RETURN_TRUE; }
static xmlDocPtr php_xsl_apply_stylesheet(zval *id, xsl_object *intern, xsltStylesheetPtr style, zval *docp) /* {{{ */ { xmlDocPtr newdocp = NULL; xmlDocPtr doc = NULL; xmlNodePtr node = NULL; xsltTransformContextPtr ctxt; php_libxml_node_object *object; char **params = NULL; int clone; zval *doXInclude, member, rv; zend_object_handlers *std_hnd; FILE *f; int secPrefsError = 0; int secPrefsValue; xsltSecurityPrefsPtr secPrefs = NULL; node = php_libxml_import_node(docp); if (node) { doc = node->doc; } if (doc == NULL) { php_error_docref(NULL, E_WARNING, "Invalid Document"); return NULL; } if (style == NULL) { php_error_docref(NULL, E_WARNING, "No stylesheet associated to this object"); return NULL; } if (intern->profiling) { if (php_check_open_basedir(intern->profiling)) { f = NULL; } else { f = VCWD_FOPEN(intern->profiling, "w"); } } else { f = NULL; } if (intern->parameter) { params = php_xsl_xslt_make_params(intern->parameter, 0); } intern->doc = emalloc(sizeof(php_libxml_node_object)); memset(intern->doc, 0, sizeof(php_libxml_node_object)); if (intern->hasKeys == 1) { doc = xmlCopyDoc(doc, 1); } else { object = Z_LIBXML_NODE_P(docp); intern->doc->document = object->document; } php_libxml_increment_doc_ref(intern->doc, doc); ctxt = xsltNewTransformContext(style, doc); ctxt->_private = (void *) intern; std_hnd = zend_get_std_object_handlers(); ZVAL_STRING(&member, "doXInclude"); doXInclude = std_hnd->read_property(id, &member, BP_VAR_IS, NULL, &rv); if (Z_TYPE_P(doXInclude) != IS_NULL) { convert_to_long(doXInclude); ctxt->xinclude = Z_LVAL_P(doXInclude); } zval_ptr_dtor(&member); secPrefsValue = intern->securityPrefs; /* if securityPrefs is set to NONE, we don't have to do any checks, but otherwise... */ if (secPrefsValue != XSL_SECPREF_NONE) { secPrefs = xsltNewSecurityPrefs(); if (secPrefsValue & XSL_SECPREF_READ_FILE ) { if (0 != xsltSetSecurityPrefs(secPrefs, XSLT_SECPREF_READ_FILE, xsltSecurityForbid)) { secPrefsError = 1; } } if (secPrefsValue & XSL_SECPREF_WRITE_FILE ) { if (0 != xsltSetSecurityPrefs(secPrefs, XSLT_SECPREF_WRITE_FILE, xsltSecurityForbid)) { secPrefsError = 1; } } if (secPrefsValue & XSL_SECPREF_CREATE_DIRECTORY ) { if (0 != xsltSetSecurityPrefs(secPrefs, XSLT_SECPREF_CREATE_DIRECTORY, xsltSecurityForbid)) { secPrefsError = 1; } } if (secPrefsValue & XSL_SECPREF_READ_NETWORK) { if (0 != xsltSetSecurityPrefs(secPrefs, XSLT_SECPREF_READ_NETWORK, xsltSecurityForbid)) { secPrefsError = 1; } } if (secPrefsValue & XSL_SECPREF_WRITE_NETWORK) { if (0 != xsltSetSecurityPrefs(secPrefs, XSLT_SECPREF_WRITE_NETWORK, xsltSecurityForbid)) { secPrefsError = 1; } } if (0 != xsltSetCtxtSecurityPrefs(secPrefs, ctxt)) { secPrefsError = 1; } } if (secPrefsError == 1) { php_error_docref(NULL, E_WARNING, "Can't set libxslt security properties, not doing transformation for security reasons"); } else { newdocp = xsltApplyStylesheetUser(style, doc, (const char**) params, NULL, f, ctxt); } if (f) { fclose(f); } xsltFreeTransformContext(ctxt); if (secPrefs) { xsltFreeSecurityPrefs(secPrefs); } if (intern->node_list != NULL) { zend_hash_destroy(intern->node_list); FREE_HASHTABLE(intern->node_list); intern->node_list = NULL; } php_libxml_decrement_doc_ref(intern->doc); efree(intern->doc); intern->doc = NULL; if (params) { clone = 0; while(params[clone]) { efree(params[clone++]); } efree(params); } return newdocp; }
static void ps_files_open(ps_files *data, const char *key) { char buf[MAXPATHLEN]; #if !defined(O_NOFOLLOW) || !defined(PHP_WIN32) struct stat sbuf; #endif int ret; if (data->fd < 0 || !data->lastkey || strcmp(key, data->lastkey)) { if (data->lastkey) { efree(data->lastkey); data->lastkey = NULL; } ps_files_close(data); if (php_session_valid_key(key) == FAILURE) { if (data->basedir) { efree(data->basedir); data->basedir = NULL; data->basedir_len = 0; } efree(data); php_error_docref(NULL, E_WARNING, "The session id is too long or contains illegal characters, valid characters are a-z, A-Z, 0-9 and '-,'"); return; } if (!ps_files_path_create(buf, sizeof(buf), data, key)) { return; } data->lastkey = estrdup(key); /* O_NOFOLLOW to prevent us from following evil symlinks */ #ifdef O_NOFOLLOW data->fd = VCWD_OPEN_MODE(buf, O_CREAT | O_RDWR | O_BINARY | O_NOFOLLOW, data->filemode); #else /* Check to make sure that the opened file is not outside of allowable dirs. This is not 100% safe but it's hard to do something better without O_NOFOLLOW */ if(PG(open_basedir) && lstat(buf, &sbuf) == 0 && S_ISLNK(sbuf.st_mode) && php_check_open_basedir(buf)) { return; } data->fd = VCWD_OPEN_MODE(buf, O_CREAT | O_RDWR | O_BINARY, data->filemode); #endif if (data->fd != -1) { #ifndef PHP_WIN32 /* check that this session file was created by us or root – we don't want to end up accepting the sessions of another webapp */ if (fstat(data->fd, &sbuf) || (sbuf.st_uid != 0 && sbuf.st_uid != getuid() && sbuf.st_uid != geteuid())) { close(data->fd); data->fd = -1; return; } #endif do { ret = flock(data->fd, LOCK_EX); } while (ret == -1 && errno == EINTR); #ifdef F_SETFD # ifndef FD_CLOEXEC # define FD_CLOEXEC 1 # endif if (fcntl(data->fd, F_SETFD, FD_CLOEXEC)) { php_error_docref(NULL, E_WARNING, "fcntl(%d, F_SETFD, FD_CLOEXEC) failed: %s (%d)", data->fd, strerror(errno), errno); } #endif } else { php_error_docref(NULL, E_WARNING, "open(%s, O_RDWR) failed: %s (%d)", buf, strerror(errno), errno); } } }
static void php_do_chown(INTERNAL_FUNCTION_PARAMETERS, int do_lchown) { zval **filename, **user; int ret; uid_t uid; if (ZEND_NUM_ARGS()!=2 || zend_get_parameters_ex(2, &filename, &user)==FAILURE) { WRONG_PARAM_COUNT; } convert_to_string_ex(filename); if (Z_TYPE_PP(user) == IS_STRING) { #if defined(ZTS) && defined(_SC_GETPW_R_SIZE_MAX) && defined(HAVE_GETPWNAM_R) struct passwd pw; struct passwd *retpwptr = NULL; long pwbuflen = sysconf(_SC_GETPW_R_SIZE_MAX); char *pwbuf; if (pwbuflen < 1) { RETURN_FALSE; } pwbuf = emalloc(pwbuflen); if (getpwnam_r(Z_STRVAL_PP(user), &pw, pwbuf, pwbuflen, &retpwptr) != 0 || retpwptr == NULL) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find uid for %s", Z_STRVAL_PP(user)); efree(pwbuf); RETURN_FALSE; } efree(pwbuf); uid = pw.pw_uid; #else struct passwd *pw = getpwnam(Z_STRVAL_PP(user)); if (!pw) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find uid for %s", Z_STRVAL_PP(user)); RETURN_FALSE; } uid = pw->pw_uid; #endif } else { convert_to_long_ex(user); uid = Z_LVAL_PP(user); } if (PG(safe_mode) &&(!php_checkuid(Z_STRVAL_PP(filename), NULL, CHECKUID_ALLOW_FILE_NOT_EXISTS))) { RETURN_FALSE; } /* Check the basedir */ if (php_check_open_basedir(Z_STRVAL_PP(filename) TSRMLS_CC)) { RETURN_FALSE; } if (do_lchown) { #if HAVE_LCHOWN ret = VCWD_LCHOWN(Z_STRVAL_PP(filename), uid, -1); #endif } else { ret = VCWD_CHOWN(Z_STRVAL_PP(filename), uid, -1); } if (ret == -1) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", strerror(errno)); RETURN_FALSE; } }
static void php_do_chgrp(INTERNAL_FUNCTION_PARAMETERS, int do_lchgrp) { zval **filename, **group; gid_t gid; int ret; if (ZEND_NUM_ARGS()!=2 || zend_get_parameters_ex(2, &filename, &group)==FAILURE) { WRONG_PARAM_COUNT; } convert_to_string_ex(filename); if (Z_TYPE_PP(group) == IS_STRING) { #if defined(ZTS) && defined(HAVE_GETGRNAM_R) && defined(_SC_GETGR_R_SIZE_MAX) struct group gr; struct group *retgrptr; long grbuflen = sysconf(_SC_GETGR_R_SIZE_MAX); char *grbuf; if (grbuflen < 1) { RETURN_FALSE; } grbuf = emalloc(grbuflen); if (getgrnam_r(Z_STRVAL_PP(group), &gr, grbuf, grbuflen, &retgrptr) != 0 || retgrptr == NULL) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find gid for %s", Z_STRVAL_PP(group)); efree(grbuf); RETURN_FALSE; } efree(grbuf); gid = gr.gr_gid; #else struct group *gr = getgrnam(Z_STRVAL_PP(group)); if (!gr) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find gid for %s", Z_STRVAL_PP(group)); RETURN_FALSE; } gid = gr->gr_gid; #endif } else { convert_to_long_ex(group); gid = Z_LVAL_PP(group); } if (PG(safe_mode) &&(!php_checkuid(Z_STRVAL_PP(filename), NULL, CHECKUID_ALLOW_FILE_NOT_EXISTS))) { RETURN_FALSE; } /* Check the basedir */ if (php_check_open_basedir(Z_STRVAL_PP(filename) TSRMLS_CC)) { RETURN_FALSE; } if (do_lchgrp) { #if HAVE_LCHOWN ret = VCWD_LCHOWN(Z_STRVAL_PP(filename), -1, gid); #endif } else { ret = VCWD_CHOWN(Z_STRVAL_PP(filename), -1, gid); } if (ret == -1) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", strerror(errno)); RETURN_FALSE; } RETURN_TRUE; }
static void _php_image_output_ctx(INTERNAL_FUNCTION_PARAMETERS, int image_type, char *tn, void (*func_p)()) { zval **imgind, **file, **quality; gdImagePtr im; char *fn = NULL; FILE *fp = NULL; int argc = ZEND_NUM_ARGS(); int q = -1, i; gdIOCtx *ctx; GDLS_FETCH(); /* The quality parameter for Wbmp stands for the threshold when called from image2wbmp() */ if (argc < 1 || argc > 3 || zend_get_parameters_ex(argc, &imgind, &file, &quality) == FAILURE) { WRONG_PARAM_COUNT; } ZEND_FETCH_RESOURCE(im, gdImagePtr, imgind, -1, "Image", le_gd); if (argc > 1) { convert_to_string_ex(file); fn = Z_STRVAL_PP(file); if (argc == 3) { convert_to_long_ex(quality); q = Z_LVAL_PP(quality); } } if ((argc == 2) || (argc == 3 && Z_STRLEN_PP(file))) { if (!fn || fn == empty_string || php_check_open_basedir(fn)) { php_error(E_WARNING, "%s: invalid filename '%s'", get_active_function_name(), fn); RETURN_FALSE; } fp = VCWD_FOPEN(fn, "wb"); if (!fp) { php_error(E_WARNING, "%s: unable to open '%s' for writing", get_active_function_name(), fn); RETURN_FALSE; } ctx = gdNewFileCtx(fp); } else { ctx = emalloc(sizeof(gdIOCtx)); ctx->putC = _php_image_output_putc; ctx->putBuf = _php_image_output_putbuf; ctx->free = _php_image_output_ctxfree; #if APACHE && defined(CHARSET_EBCDIC) /* XXX this is unlikely to work any more [email protected] */ SLS_FETCH(); /* This is a binary file already: avoid EBCDIC->ASCII conversion */ ap_bsetflag(php3_rqst->connection->client, B_EBCDIC2ASCII, 0); #endif } switch(image_type) { case PHP_GDIMG_CONVERT_WBM: if(q<0||q>255) { php_error(E_WARNING, "%s: invalid threshold value '%d'. It must be between 0 and 255",get_active_function_name(), q); } case PHP_GDIMG_TYPE_JPG: (*func_p)(im, ctx, q); break; case PHP_GDIMG_TYPE_WBM: for(i=0; i < gdImageColorsTotal(im); i++) { if(gdImageRed(im, i) == 0) break; } (*func_p)(im, i, ctx); break; default: (*func_p)(im, ctx); break; } ctx->free(ctx); if(fp) { fflush(fp); fclose(fp); } RETURN_TRUE; }
/* {{{ proto int pspell_new_personal(string personal, string language [, string spelling [, string jargon [, string encoding [, int mode]]]]) Load a dictionary with a personal wordlist*/ static PHP_FUNCTION(pspell_new_personal) { char *personal, *language, *spelling = NULL, *jargon = NULL, *encoding = NULL; size_t personal_len, language_len, spelling_len = 0, jargon_len = 0, encoding_len = 0; zend_long mode = Z_L(0), speed = Z_L(0); int argc = ZEND_NUM_ARGS(); zval *ind; #ifdef PHP_WIN32 TCHAR aspell_dir[200]; TCHAR data_dir[220]; TCHAR dict_dir[220]; HKEY hkey; DWORD dwType,dwLen; #endif PspellCanHaveError *ret; PspellManager *manager; PspellConfig *config; if (zend_parse_parameters(argc, "ps|sssl", &personal, &personal_len, &language, &language_len, &spelling, &spelling_len, &jargon, &jargon_len, &encoding, &encoding_len, &mode) == FAILURE) { return; } config = new_pspell_config(); #ifdef PHP_WIN32 /* If aspell was installed using installer, we should have a key * pointing to the location of the dictionaries */ if (0 == RegOpenKey(HKEY_LOCAL_MACHINE, "Software\\Aspell", &hkey)) { LONG result; dwLen = sizeof(aspell_dir) - 1; result = RegQueryValueEx(hkey, "", NULL, &dwType, (LPBYTE)&aspell_dir, &dwLen); RegCloseKey(hkey); if (result == ERROR_SUCCESS) { strlcpy(data_dir, aspell_dir, sizeof(data_dir)); strlcat(data_dir, "\\data", sizeof(data_dir)); strlcpy(dict_dir, aspell_dir, sizeof(dict_dir)); strlcat(dict_dir, "\\dict", sizeof(dict_dir)); pspell_config_replace(config, "data-dir", data_dir); pspell_config_replace(config, "dict-dir", dict_dir); } } #endif if (php_check_open_basedir(personal)) { delete_pspell_config(config); RETURN_FALSE; } pspell_config_replace(config, "personal", personal); pspell_config_replace(config, "save-repl", "false"); pspell_config_replace(config, "language-tag", language); if (spelling_len) { pspell_config_replace(config, "spelling", spelling); } if (jargon_len) { pspell_config_replace(config, "jargon", jargon); } if (encoding_len) { pspell_config_replace(config, "encoding", encoding); } if (argc > 5) { speed = mode & PSPELL_SPEED_MASK_INTERNAL; /* First check what mode we want (how many suggestions) */ if (speed == PSPELL_FAST) { pspell_config_replace(config, "sug-mode", "fast"); } else if (speed == PSPELL_NORMAL) { pspell_config_replace(config, "sug-mode", "normal"); } else if (speed == PSPELL_BAD_SPELLERS) { pspell_config_replace(config, "sug-mode", "bad-spellers"); } /* Then we see if run-together words should be treated as valid components */ if (mode & PSPELL_RUN_TOGETHER) { pspell_config_replace(config, "run-together", "true"); } } ret = new_pspell_manager(config); delete_pspell_config(config); if (pspell_error_number(ret) != 0) { php_error_docref(NULL, E_WARNING, "PSPELL couldn't open the dictionary. reason: %s", pspell_error_message(ret)); delete_pspell_can_have_error(ret); RETURN_FALSE; } manager = to_pspell_manager(ret); ind = zend_list_insert(manager, le_pspell); RETURN_LONG(Z_RES_HANDLE_P(ind)); }
/* {{{ php_oci_lob_import() Import LOB contents from the given file */ int php_oci_lob_import (php_oci_descriptor *descriptor, char *filename) { int fp; ub4 loblen; OCILobLocator *lob = (OCILobLocator *)descriptor->descriptor; php_oci_connection *connection = descriptor->connection; char buf[8192]; ub4 offset = 1; sword errstatus; #if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION > 3) || (PHP_MAJOR_VERSION > 5) /* Safe mode has been removed in PHP 5.4 */ if (php_check_open_basedir(filename)) { #else if ((PG(safe_mode) && (!php_checkuid(filename, NULL, CHECKUID_CHECK_FILE_AND_DIR))) || php_check_open_basedir(filename)) { #endif return 1; } if ((fp = VCWD_OPEN(filename, O_RDONLY|O_BINARY)) == -1) { php_error_docref(NULL, E_WARNING, "Can't open file %s", filename); return 1; } while ((loblen = read(fp, &buf, sizeof(buf))) > 0) { PHP_OCI_CALL_RETURN(errstatus, OCILobWrite, ( connection->svc, connection->err, lob, &loblen, offset, (dvoid *) &buf, loblen, OCI_ONE_PIECE, (dvoid *)0, (OCICallbackLobWrite) 0, (ub2) descriptor->charset_id, (ub1) descriptor->charset_form ) ); if (errstatus != OCI_SUCCESS) { connection->errcode = php_oci_error(connection->err, errstatus); PHP_OCI_HANDLE_ERROR(connection, connection->errcode); close(fp); return 1; } else { connection->errcode = 0; /* retain backwards compat with OCI8 1.4 */ } offset += loblen; } close(fp); return 0; } /* }}} */ /* {{{ php_oci_lob_append() Append data to the end of the LOB */ int php_oci_lob_append (php_oci_descriptor *descriptor_dest, php_oci_descriptor *descriptor_from) { php_oci_connection *connection = descriptor_dest->connection; OCILobLocator *lob_dest = descriptor_dest->descriptor; OCILobLocator *lob_from = descriptor_from->descriptor; ub4 dest_len, from_len; sword errstatus; if (php_oci_lob_get_length(descriptor_dest, &dest_len)) { return 1; } if (php_oci_lob_get_length(descriptor_from, &from_len)) { return 1; } if (from_len <= 0) { return 0; } PHP_OCI_CALL_RETURN(errstatus, OCILobAppend, (connection->svc, connection->err, lob_dest, lob_from)); if (errstatus != OCI_SUCCESS) { connection->errcode = php_oci_error(connection->err, errstatus); PHP_OCI_HANDLE_ERROR(connection, connection->errcode); return 1; } connection->errcode = 0; /* retain backwards compat with OCI8 1.4 */ return 0; }
/* {{{ php_open_temporary_file * * Unlike tempnam(), the supplied dir argument takes precedence * over the TMPDIR environment variable * This function should do its best to return a file pointer to a newly created * unique file, on every platform. */ PHPAPI int php_open_temporary_fd_ex(const char *dir, const char *pfx, zend_string **opened_path_p, uint32_t flags) { int fd; const char *temp_dir; if (!pfx) { pfx = "tmp."; } if (opened_path_p) { *opened_path_p = NULL; } if (!dir || *dir == '\0') { def_tmp: temp_dir = php_get_temporary_directory(); if (temp_dir && *temp_dir != '\0' && (!(flags & PHP_TMP_FILE_OPEN_BASEDIR_CHECK) || !php_check_open_basedir(temp_dir))) { return php_do_open_temporary_file(temp_dir, pfx, opened_path_p); } else { return -1; } } /* Try the directory given as parameter. */ fd = php_do_open_temporary_file(dir, pfx, opened_path_p); if (fd == -1) { /* Use default temporary directory. */ if (!(flags & PHP_TMP_FILE_SILENT)) { php_error_docref(NULL, E_NOTICE, "file created in the system's temporary directory"); } goto def_tmp; } return fd; }
/* ArchiveReader::__construct {{{ * */ ZEND_METHOD(ArchiveReader, __construct) { archive_file_t *arch = NULL; int resource_id; zval *this = getThis(); const char *error_string = NULL; char *filename; long error_num, filename_len, result, format = 0, compression = 0, block_size = 0; zend_error_handling error_handling; zend_replace_error_handling(EH_THROW, ce_ArchiveException, &error_handling TSRMLS_CC); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|lll", &filename, &filename_len, &format, &compression, &block_size) == FAILURE) { zend_restore_error_handling(&error_handling TSRMLS_CC); return; } #if PHP_API_VERSION < 20100412 if (PG(safe_mode) && (!php_checkuid(filename, NULL, CHECKUID_CHECK_FILE_AND_DIR))) { zend_restore_error_handling(&error_handling TSRMLS_CC); return; } #endif if (php_check_open_basedir(filename TSRMLS_CC)) { zend_restore_error_handling(&error_handling TSRMLS_CC); return; } if(block_size <= 0){ block_size = PHP_ARCHIVE_BUF_LEN; } arch = (archive_file_t *) emalloc(sizeof(archive_file_t)); arch->stream = NULL; arch->current_entry = NULL; arch->entries = NULL; arch->struct_state = ARCHIVE_OK; arch->block_size = block_size; arch->mode = PHP_ARCHIVE_READ_MODE; arch->buf = emalloc(arch->block_size + 1); arch->filename = estrndup(filename, filename_len); arch->arch = archive_read_new(); archive_read_support_filter_all(arch->arch); switch(format){ case PHP_ARCHIVE_FORMAT_TAR: archive_read_support_format_tar(arch->arch); break; case PHP_ARCHIVE_FORMAT_CPIO: archive_read_support_format_cpio(arch->arch); break; default: archive_read_support_format_all(arch->arch); break; } switch(compression){ case PHP_ARCHIVE_COMPRESSION_NONE: break; case PHP_ARCHIVE_COMPRESSION_GZIP: if(archive_read_support_filter_gzip(arch->arch) != ARCHIVE_OK){ efree(arch->filename); efree(arch->buf); efree(arch); php_error_docref(NULL TSRMLS_CC, E_WARNING, "Gzip compression support is not available in this build "); zend_restore_error_handling(&error_handling TSRMLS_CC); return; } break; case PHP_ARCHIVE_COMPRESSION_BZIP2: if(archive_read_support_filter_gzip(arch->arch) != ARCHIVE_OK){ efree(arch->filename); efree(arch->buf); efree(arch); php_error_docref(NULL TSRMLS_CC, E_WARNING, "Bzip2 compression support is not available in this build "); zend_restore_error_handling(&error_handling TSRMLS_CC); return; } default: archive_read_support_filter_all(arch->arch); break; } result = archive_read_open(arch->arch, arch, _archive_open_clbk, _archive_read_clbk, _archive_close_clbk); if (result) { error_num = archive_errno(arch->arch); error_string = archive_error_string(arch->arch); if (arch->stream) { php_stream_close(arch->stream); } if (error_num && error_string) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to open file %s for reading: error #%d, %s", filename, error_num, error_string); } else { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to open file %s for reading: unknown error %d", filename, result); } zend_restore_error_handling(&error_handling TSRMLS_CC); archive_read_close(arch->arch); archive_read_free(arch->arch); efree(arch->filename); efree(arch->buf); efree(arch); return; } resource_id = zend_list_insert(arch,le_archive); add_property_resource(this, "fd", resource_id); zend_restore_error_handling(&error_handling TSRMLS_CC); return; }
/* ArchiveWriter::__construct {{{ * */ ZEND_METHOD(ArchiveWriter, __construct) { archive_file_t *arch = NULL; int resource_id; zval *this = getThis(); const char *error_string = NULL; char *filename; long error_num, filename_len, result, format=0, compression=0; zend_error_handling error_handling; zend_replace_error_handling(EH_THROW, ce_ArchiveException, &error_handling TSRMLS_CC); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|ll", &filename, &filename_len, &format, &compression) == FAILURE) { zend_restore_error_handling(&error_handling TSRMLS_CC); return; } #if PHP_API_VERSION < 20100412 if (PG(safe_mode) && (!php_checkuid(filename, NULL, CHECKUID_CHECK_FILE_AND_DIR))) { zend_restore_error_handling(&error_handling TSRMLS_CC); return; } #endif if (php_check_open_basedir(filename TSRMLS_CC)) { zend_restore_error_handling(&error_handling TSRMLS_CC); return; } arch = (archive_file_t *) emalloc(sizeof(archive_file_t)); arch->stream = NULL; ALLOC_HASHTABLE(arch->entries); zend_hash_init(arch->entries, 10, NULL, _archive_entries_hash_dtor, 0); arch->mode = PHP_ARCHIVE_WRITE_MODE; arch->buf = emalloc(PHP_ARCHIVE_BUF_LEN + 1); arch->filename = estrndup(filename, filename_len); arch->arch = archive_write_new(); switch (compression) { case PHP_ARCHIVE_COMPRESSION_GZIP: if (archive_write_add_filter_gzip(arch->arch) != ARCHIVE_OK) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Gzip compression is not supported in this build"); zend_restore_error_handling(&error_handling TSRMLS_CC); return; } break; case PHP_ARCHIVE_COMPRESSION_BZIP2: if (archive_write_add_filter_bzip2(arch->arch) != ARCHIVE_OK) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Bzip2 compression is not supported in this build"); zend_restore_error_handling(&error_handling TSRMLS_CC); return; } break; case 0: /* default value */ case PHP_ARCHIVE_COMPRESSION_NONE: /* always supported */ break; default: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unsupported compression type %ld", compression); zend_restore_error_handling(&error_handling TSRMLS_CC); return; break; } switch (format) { case 0: /* default value */ case PHP_ARCHIVE_FORMAT_TAR: case PHP_ARCHIVE_FORMAT_PAX_RESTRICTED: archive_write_set_format_pax_restricted(arch->arch); break; case PHP_ARCHIVE_FORMAT_PAX: archive_write_set_format_pax(arch->arch); break; case PHP_ARCHIVE_FORMAT_CPIO: archive_write_set_format_cpio(arch->arch); break; case PHP_ARCHIVE_FORMAT_SHAR: archive_write_set_format_shar(arch->arch); break; case PHP_ARCHIVE_FORMAT_USTAR: archive_write_set_format_ustar(arch->arch); break; default: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unsupported archive format: %ld", format); zend_restore_error_handling(&error_handling TSRMLS_CC); return; break; } archive_write_set_bytes_per_block(arch->arch, DEFAULT_BYTES_PER_BLOCK); result = archive_write_open(arch->arch, arch, _archive_open_clbk, _archive_write_clbk, _archive_close_clbk); /* do not pad the last block */ archive_write_set_bytes_in_last_block(arch->arch, 1); if (result) { error_num = archive_errno(arch->arch); error_string = archive_error_string(arch->arch); efree(arch->filename); efree(arch->buf); efree(arch); if (error_num && error_string) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to open file %s for writing: error #%ld, %s", filename, error_num, error_string); } else { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to open file %s for writing: unknown error %ld", filename, result); } zend_restore_error_handling(&error_handling TSRMLS_CC); return; } resource_id = zend_list_insert(arch,le_archive); add_property_resource(this, "fd", resource_id); zend_restore_error_handling(&error_handling TSRMLS_CC); return; }
/* {{{ 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; }
static void _php_do_opendir(INTERNAL_FUNCTION_PARAMETERS, int createobject) { pval **arg; php_dir *dirp; DIRLS_FETCH(); if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &arg) == FAILURE) { WRONG_PARAM_COUNT; } convert_to_string_ex(arg); if (php_check_open_basedir((*arg)->value.str.val)) { RETURN_FALSE; } dirp = emalloc(sizeof(php_dir)); dirp->dir = VCWD_OPENDIR((*arg)->value.str.val); #ifdef PHP_WIN32 if (!dirp->dir || dirp->dir->finished) { if (dirp->dir) { closedir(dirp->dir); } #else if (!dirp->dir) { #endif efree(dirp); php_error(E_WARNING, "OpenDir: %s (errno %d)", strerror(errno), errno); RETURN_FALSE; } dirp->id = zend_list_insert(dirp,le_dirp); php_set_default_dir(dirp->id DIRLS_CC); if (createobject) { object_init_ex(return_value, dir_class_entry_ptr); add_property_stringl(return_value, "path", (*arg)->value.str.val, (*arg)->value.str.len, 1); add_property_resource(return_value, "handle", dirp->id); zend_list_addref(dirp->id); } else { RETURN_RESOURCE(dirp->id); } } /* }}} */ /* {{{ proto int opendir(string path) Open a directory and return a dir_handle */ PHP_FUNCTION(opendir) { _php_do_opendir(INTERNAL_FUNCTION_PARAM_PASSTHRU,0); } /* }}} */ /* {{{ proto class dir(string directory) Directory class with properties, handle and class and methods read, rewind and close */ PHP_FUNCTION(getdir) { _php_do_opendir(INTERNAL_FUNCTION_PARAM_PASSTHRU,1); } /* }}} */ /* {{{ proto void closedir([int dir_handle]) Close directory connection identified by the dir_handle */ PHP_FUNCTION(closedir) { pval **id, **tmp, *myself; php_dir *dirp; DIRLS_FETCH(); FETCH_DIRP(); zend_list_delete(dirp->id); if (dirp->id == DIRG(default_dir)) { php_set_default_dir(-1 DIRLS_CC); } } /* }}} */ #if defined(HAVE_CHROOT) && !defined(ZTS) /* {{{ proto int chroot(string directory) Change root directory */ PHP_FUNCTION(chroot) { pval **arg; int ret; if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &arg) == FAILURE) { WRONG_PARAM_COUNT; } convert_to_string_ex(arg); ret = chroot((*arg)->value.str.val); if (ret != 0) { php_error(E_WARNING, "chroot: %s (errno %d)", strerror(errno), errno); RETURN_FALSE; } ret = chdir("/"); if (ret != 0) { php_error(E_WARNING, "chdir: %s (errno %d)", strerror(errno), errno); RETURN_FALSE; } RETURN_TRUE; } /* }}} */ #endif /* {{{ proto int chdir(string directory) Change the current directory */ PHP_FUNCTION(chdir) { pval **arg; int ret; PLS_FETCH(); if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &arg) == FAILURE) { WRONG_PARAM_COUNT; } convert_to_string_ex(arg); if (PG(safe_mode) && !php_checkuid((*arg)->value.str.val, NULL, CHECKUID_ALLOW_ONLY_DIR)) { RETURN_FALSE; } ret = VCWD_CHDIR((*arg)->value.str.val); if (ret != 0) { php_error(E_WARNING, "ChDir: %s (errno %d)", strerror(errno), errno); RETURN_FALSE; } RETURN_TRUE; } /* }}} */ /* {{{ proto string getcwd(void) Gets the current directory */ PHP_FUNCTION(getcwd) { char path[MAXPATHLEN]; char *ret=NULL; if (ZEND_NUM_ARGS() != 0) { WRONG_PARAM_COUNT; } #if HAVE_GETCWD ret = VCWD_GETCWD(path, MAXPATHLEN); #elif HAVE_GETWD ret = VCWD_GETWD(path); /* * #warning is not ANSI C * #else * #warning no proper getcwd support for your site */ #endif if (ret) { RETURN_STRING(path,1); } else { RETURN_FALSE; } } /* }}} */ /* {{{ proto void rewinddir([int dir_handle]) Rewind dir_handle back to the start */ PHP_FUNCTION(rewinddir) { pval **id, **tmp, *myself; php_dir *dirp; DIRLS_FETCH(); FETCH_DIRP(); rewinddir(dirp->dir); } /* }}} */ /* {{{ proto string readdir([int dir_handle]) Read directory entry from dir_handle */ PHP_NAMED_FUNCTION(php_if_readdir) { pval **id, **tmp, *myself; php_dir *dirp; char entry[sizeof(struct dirent)+MAXPATHLEN]; struct dirent *result = (struct dirent *)&entry; /* patch for libc5 readdir problems */ DIRLS_FETCH(); FETCH_DIRP(); if (php_readdir_r(dirp->dir, (struct dirent *) entry, &result) == 0 && result) { RETURN_STRINGL(result->d_name, strlen(result->d_name), 1); } RETURN_FALSE; }