static void suhosin_op_array_ctor(zend_op_array *op_array) { TSRMLS_FETCH(); if (suhosin_zend_extension_entry.resource_number != -1) { unsigned long suhosin_flags = 0; if (SUHOSIN_G(in_code_type) == SUHOSIN_EVAL) { suhosin_flags |= SUHOSIN_FLAG_CREATED_BY_EVAL; } op_array->reserved[suhosin_zend_extension_entry.resource_number] = (void *)suhosin_flags; } }
static int suhosin_module_startup(zend_extension *extension) { zend_module_entry *module_entry_ptr; int resid; TSRMLS_FETCH(); /* zend_register_module(&suhosin_module_entry TSRMLS_CC); */ if (zend_hash_find(&module_registry, "suhosin", sizeof("suhosin"), (void **)&module_entry_ptr)==SUCCESS) { if (extension) { extension->handle = module_entry_ptr->handle; } else { zend_extension ext; ext = suhosin_zend_extension_entry; ext.handle = module_entry_ptr->handle; /* zend_llist_add_element(&zend_extensions, &ext); extension = zend_llist_get_last(&zend_extensions); */ extension = &suhosin_zend_extension_entry; } module_entry_ptr->handle = NULL; } else { return FAILURE; } if (SUHOSIN_G(apc_bug_workaround)) { resid = zend_get_resource_handle(extension); } resid = zend_get_resource_handle(extension); suhosin_zend_extension_entry.resource_number = resid; suhosin_hook_treat_data(); suhosin_hook_post_handlers(TSRMLS_C); suhosin_aes_gentables(); suhosin_hook_register_server_variables(); suhosin_hook_header_handler(); suhosin_hook_execute(TSRMLS_C); suhosin_hook_session(TSRMLS_C); return SUCCESS; }
/* {{{ PHP_INI_MH */ static PHP_INI_MH(suhosin_OnChangeMemoryLimit) { #if SIZEOF_LONG==8 long hard_memory_limit = 0x7fffffffffffffff; #elif SIZEOF_LONG==4 long hard_memory_limit = 0x7fffffff; #endif /* will produce a compile error or SIZEOF_LONG is not 4 or 8 */ if (stage == ZEND_INI_STAGE_RUNTIME) { if (SUHOSIN_G(memory_limit) > 0) { SUHOSIN_G(hard_memory_limit) = SUHOSIN_G(memory_limit); } else if (SUHOSIN_G(hard_memory_limit) == 0) { SUHOSIN_G(hard_memory_limit) = PG(memory_limit); } hard_memory_limit = SUHOSIN_G(hard_memory_limit); } else { SUHOSIN_G(hard_memory_limit) = 0; } if (new_value) { PG(memory_limit) = zend_atol(new_value, new_value_length); if (hard_memory_limit > 0) { if (PG(memory_limit) > hard_memory_limit) { suhosin_log(S_MISC, "script tried to increase memory_limit to %lu bytes which is above the allowed value", PG(memory_limit)); if (!SUHOSIN_G(simulation)) { PG(memory_limit) = hard_memory_limit; return FAILURE; } } else if (PG(memory_limit) < 0) { suhosin_log(S_MISC, "script tried to disable memory_limit by setting it to a negative value %ld bytes which is not allowed", PG(memory_limit)); if (!SUHOSIN_G(simulation)) { PG(memory_limit) = hard_memory_limit; return FAILURE; } } } } else { PG(memory_limit) = hard_memory_limit; } return zend_set_memory_limit(PG(memory_limit)); }
/* {{{ SAPI_UPLOAD_VARNAME_FILTER_FUNC */ static int check_fileupload_varname(char *varname) { char *index, *prev_index = NULL, *var; unsigned int var_len, total_len, depth = 0; TSRMLS_FETCH(); var = estrdup(varname); /* Normalize the variable name */ normalize_varname(var); /* Find length of variable name */ index = strchr(var, '['); total_len = strlen(var); var_len = index ? index-var : total_len; /* Drop this variable if it exceeds the varname/total length limit */ if (SUHOSIN_G(max_varname_length) && SUHOSIN_G(max_varname_length) < var_len) { suhosin_log(S_FILES, "configured request variable name length limit exceeded - dropped variable '%s'", var); if (!SUHOSIN_G(simulation)) { goto return_failure; } } if (SUHOSIN_G(max_totalname_length) && SUHOSIN_G(max_totalname_length) < total_len) { suhosin_log(S_FILES, "configured request variable total name length limit exceeded - dropped variable '%s'", var); if (!SUHOSIN_G(simulation)) { goto return_failure; } } if (SUHOSIN_G(max_post_name_length) && SUHOSIN_G(max_post_name_length) < var_len) { suhosin_log(S_FILES, "configured POST variable name length limit exceeded - dropped variable '%s'", var); if (!SUHOSIN_G(simulation)) { goto return_failure; } } if (SUHOSIN_G(max_post_totalname_length) && SUHOSIN_G(max_post_totalname_length) < var_len) { suhosin_log(S_FILES, "configured POST variable total name length limit exceeded - dropped variable '%s'", var); if (!SUHOSIN_G(simulation)) { goto return_failure; } } /* Find out array depth */ while (index) { char *index_end; unsigned int index_length; /* overjump '[' */ index++; /* increase array depth */ depth++; index_end = strchr(index, ']'); if (index_end == NULL) { index_end = index+strlen(index); } index_length = index_end - index; if (SUHOSIN_G(max_array_index_length) && SUHOSIN_G(max_array_index_length) < index_length) { suhosin_log(S_FILES, "configured request variable array index length limit exceeded - dropped variable '%s'", var); if (!SUHOSIN_G(simulation)) { goto return_failure; } } if (SUHOSIN_G(max_post_array_index_length) && SUHOSIN_G(max_post_array_index_length) < index_length) { suhosin_log(S_FILES, "configured POST variable array index length limit exceeded - dropped variable '%s'", var); if (!SUHOSIN_G(simulation)) { goto return_failure; } } index = strchr(index, '['); } /* Drop this variable if it exceeds the array depth limit */ if (SUHOSIN_G(max_array_depth) && SUHOSIN_G(max_array_depth) < depth) { suhosin_log(S_FILES, "configured request variable array depth limit exceeded - dropped variable '%s'", var); if (!SUHOSIN_G(simulation)) { goto return_failure; } } if (SUHOSIN_G(max_post_array_depth) && SUHOSIN_G(max_post_array_depth) < depth) { suhosin_log(S_FILES, "configured POST variable array depth limit exceeded - dropped variable '%s'", var); if (!SUHOSIN_G(simulation)) { goto return_failure; } } /* Drop this variable if it is one of GLOBALS, _GET, _POST, ... */ /* This is to protect several silly scripts that do globalizing themself */ if (is_protected_varname(var, var_len)) { suhosin_log(S_FILES, "tried to register forbidden variable '%s' through FILE variables", var); if (!SUHOSIN_G(simulation)) { goto return_failure; } } efree(var); return SUCCESS; return_failure: efree(var); return FAILURE; }
PHP_SUHOSIN_API void suhosin_log(int loglevel, char *fmt, ...) { int s, r, i=0, fd; long written, towrite; int getcaller=0; char *wbuf; struct timeval tv; time_t now; struct tm tm; #if defined(AF_UNIX) struct sockaddr_un saun; #endif #ifdef PHP_WIN32 LPTSTR strs[2]; unsigned short etype; DWORD evid; #endif char buf[5000]; char error[5000]; char *ip_address; char *fname; char *alertstring; int lineno; va_list ap; TSRMLS_FETCH(); #if PHP_VERSION_ID >= 50500 getcaller = (loglevel & S_GETCALLER) == S_GETCALLER; #endif /* remove the S_GETCALLER flag */ loglevel = loglevel & ~S_GETCALLER; SDEBUG("(suhosin_log) loglevel: %d log_syslog: %u - log_sapi: %u - log_script: %u", loglevel, SUHOSIN_G(log_syslog), SUHOSIN_G(log_sapi), SUHOSIN_G(log_script)); /* dump core if wanted */ if (SUHOSIN_G(coredump) && loglevel == S_MEMORY) { volatile unsigned int *x = 0; volatile int y = *x; } if (SUHOSIN_G(log_use_x_forwarded_for)) { ip_address = suhosin_getenv("HTTP_X_FORWARDED_FOR", 20 TSRMLS_CC); if (ip_address == NULL) { ip_address = "X-FORWARDED-FOR not set"; } } else { ip_address = suhosin_getenv("REMOTE_ADDR", 11 TSRMLS_CC); if (ip_address == NULL) { ip_address = "REMOTE_ADDR not set"; } } va_start(ap, fmt); ap_php_vsnprintf(error, sizeof(error), fmt, ap); va_end(ap); while (error[i]) { if (error[i] < 32) error[i] = '.'; i++; } if (SUHOSIN_G(simulation)) { alertstring = "ALERT-SIMULATION"; } else { alertstring = "ALERT"; } if (zend_is_executing(TSRMLS_C)) { zend_execute_data *exdata = EG(current_execute_data); if (exdata) { if (getcaller && exdata->prev_execute_data) { lineno = exdata->prev_execute_data->opline->lineno; fname = (char *)exdata->prev_execute_data->op_array->filename; } else { lineno = exdata->opline->lineno; fname = (char *)exdata->op_array->filename; } } else { lineno = zend_get_executed_lineno(TSRMLS_C); fname = (char *)zend_get_executed_filename(TSRMLS_C); } ap_php_snprintf(buf, sizeof(buf), "%s - %s (attacker '%s', file '%s', line %u)", alertstring, error, ip_address, fname, lineno); } else { fname = suhosin_getenv("SCRIPT_FILENAME", 15 TSRMLS_CC); if (fname==NULL) { fname = "unknown"; } ap_php_snprintf(buf, sizeof(buf), "%s - %s (attacker '%s', file '%s')", alertstring, error, ip_address, fname); } /* Syslog-Logging disabled? */ if (((SUHOSIN_G(log_syslog)|S_INTERNAL) & loglevel)==0) { goto log_file; } #if defined(AF_UNIX) ap_php_snprintf(error, sizeof(error), "<%u>suhosin[%u]: %s\n", (unsigned int)(SUHOSIN_G(log_syslog_facility)|SUHOSIN_G(log_syslog_priority)),getpid(),buf); s = socket(AF_UNIX, SOCK_DGRAM, 0); if (s == -1) { goto log_file; } memset(&saun, 0, sizeof(saun)); saun.sun_family = AF_UNIX; strcpy(saun.sun_path, SYSLOG_PATH); /*saun.sun_len = sizeof(saun);*/ r = connect(s, (struct sockaddr *)&saun, sizeof(saun)); if (r) { close(s); s = socket(AF_UNIX, SOCK_STREAM, 0); if (s == -1) { goto log_file; } memset(&saun, 0, sizeof(saun)); saun.sun_family = AF_UNIX; strcpy(saun.sun_path, SYSLOG_PATH); /*saun.sun_len = sizeof(saun);*/ r = connect(s, (struct sockaddr *)&saun, sizeof(saun)); if (r) { close(s); goto log_file; } } send(s, error, strlen(error), 0); close(s); #endif #ifdef PHP_WIN32 ap_php_snprintf(error, sizeof(error), "suhosin[%u]: %s", getpid(),buf); switch (SUHOSIN_G(log_syslog_priority)) { /* translate UNIX type into NT type */ case 1: /*LOG_ALERT:*/ etype = EVENTLOG_ERROR_TYPE; break; case 6: /*LOG_INFO:*/ etype = EVENTLOG_INFORMATION_TYPE; break; default: etype = EVENTLOG_WARNING_TYPE; } evid = loglevel; strs[0] = error; /* report the event */ if (log_source == NULL) { log_source = RegisterEventSource(NULL, "Suhosin-" SUHOSIN_EXT_VERSION); } ReportEvent(log_source, etype, (unsigned short) SUHOSIN_G(log_syslog_priority), evid, NULL, 1, 0, strs, NULL); #endif log_file: /* File-Logging disabled? */ if ((SUHOSIN_G(log_file) & loglevel)==0) { goto log_sapi; } if (!SUHOSIN_G(log_filename) || !SUHOSIN_G(log_filename)[0]) { goto log_sapi; } fd = open(SUHOSIN_G(log_filename), O_CREAT|O_APPEND|O_WRONLY, 0640); if (fd == -1) { suhosin_log(S_INTERNAL, "Unable to open logfile: %s", SUHOSIN_G(log_filename)); return; } gettimeofday(&tv, NULL); now = tv.tv_sec; php_gmtime_r(&now, &tm); ap_php_snprintf(error, sizeof(error), "%s %2d %02d:%02d:%02d [%u] %s\n", month_names[tm.tm_mon], tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, getpid(),buf); towrite = strlen(error); wbuf = error; php_flock(fd, LOCK_EX); while (towrite > 0) { written = write(fd, wbuf, towrite); if (written < 0) { break; } towrite -= written; wbuf += written; } php_flock(fd, LOCK_UN); close(fd); log_sapi: /* SAPI Logging activated? */ SDEBUG("(suhosin_log) log_syslog: %u - log_sapi: %u - log_script: %u - log_phpscript: %u", SUHOSIN_G(log_syslog), SUHOSIN_G(log_sapi), SUHOSIN_G(log_script), SUHOSIN_G(log_phpscript)); if (((SUHOSIN_G(log_sapi)|S_INTERNAL) & loglevel)!=0) { #if PHP_VERSION_ID < 50400 sapi_module.log_message(buf); #else sapi_module.log_message(buf TSRMLS_CC); #endif } if ((SUHOSIN_G(log_stdout) & loglevel)!=0) { printf("%s\n", buf); } /*log_script:*/ /* script logging activaed? */ if (((SUHOSIN_G(log_script) & loglevel)!=0) && SUHOSIN_G(log_scriptname)!=NULL) { char cmd[8192], *cmdpos, *bufpos; FILE *in; int space; struct stat st; char *sname = SUHOSIN_G(log_scriptname); while (isspace(*sname)) ++sname; if (*sname == 0) goto log_phpscript; if (VCWD_STAT(sname, &st) < 0) { suhosin_log(S_INTERNAL, "unable to find logging shell script %s - file dropped", sname); goto log_phpscript; } if (access(sname, X_OK|R_OK) < 0) { suhosin_log(S_INTERNAL, "logging shell script %s is not executable - file dropped", sname); goto log_phpscript; } /* TODO: clean up this code to calculate size of output dynamically */ ap_php_snprintf(cmd, sizeof(cmd) - 20, "%s %s \'", sname, loglevel2string(loglevel)); space = sizeof(cmd) - strlen(cmd) - 20; cmdpos = cmd + strlen(cmd); bufpos = buf; if (space <= 1) return; while (space > 2 && *bufpos) { if (*bufpos == '\'') { if (space<=5) break; *cmdpos++ = '\''; *cmdpos++ = '\\'; *cmdpos++ = '\''; *cmdpos++ = '\''; bufpos++; space-=4; } else { *cmdpos++ = *bufpos++; space--; } } *cmdpos++ = '\''; *cmdpos++ = ' '; *cmdpos++ = '2'; *cmdpos++ = '>'; *cmdpos++ = '&'; *cmdpos++ = '1'; *cmdpos = 0; if ((in=VCWD_POPEN(cmd, "r"))==NULL) { suhosin_log(S_INTERNAL, "Unable to execute logging shell script: %s", sname); goto log_phpscript; } /* read and forget the result */ while (1) { int readbytes = fread(cmd, 1, sizeof(cmd), in); if (readbytes<=0) { break; } if (strncmp(cmd, "sh: ", 4) == 0) { /* assume this is an error */ suhosin_log(S_INTERNAL, "Error while executing logging shell script: %s", sname); pclose(in); goto log_phpscript; } } pclose(in); } log_phpscript: if ((SUHOSIN_G(log_phpscript) & loglevel)!=0 && EG(in_execution) && SUHOSIN_G(log_phpscriptname) && SUHOSIN_G(log_phpscriptname)[0]) { zend_file_handle file_handle; zend_op_array *new_op_array; zval *result = NULL; long orig_execution_depth = SUHOSIN_G(execution_depth); #if PHP_VERSION_ID < 50400 zend_bool orig_safe_mode = PG(safe_mode); #endif char *orig_basedir = PG(open_basedir); char *phpscript = SUHOSIN_G(log_phpscriptname); SDEBUG("scriptname %s", SUHOSIN_G(log_phpscriptname)); #ifdef ZEND_ENGINE_2 if (zend_stream_open(phpscript, &file_handle TSRMLS_CC) == SUCCESS) { #else if (zend_open(phpscript, &file_handle) == SUCCESS && ZEND_IS_VALID_FILE_HANDLE(&file_handle)) { file_handle.filename = phpscript; file_handle.free_filename = 0; #endif if (!file_handle.opened_path) { file_handle.opened_path = estrndup(phpscript, strlen(phpscript)); } new_op_array = zend_compile_file(&file_handle, ZEND_REQUIRE TSRMLS_CC); zend_destroy_file_handle(&file_handle TSRMLS_CC); if (new_op_array) { HashTable *active_symbol_table = EG(active_symbol_table); zval *zerror, *zerror_class; if (active_symbol_table == NULL) { active_symbol_table = &EG(symbol_table); } EG(return_value_ptr_ptr) = &result; EG(active_op_array) = new_op_array; MAKE_STD_ZVAL(zerror); MAKE_STD_ZVAL(zerror_class); ZVAL_STRING(zerror, buf, 1); ZVAL_LONG(zerror_class, loglevel); zend_hash_update(active_symbol_table, "SUHOSIN_ERROR", sizeof("SUHOSIN_ERROR"), (void **)&zerror, sizeof(zval *), NULL); zend_hash_update(active_symbol_table, "SUHOSIN_ERRORCLASS", sizeof("SUHOSIN_ERRORCLASS"), (void **)&zerror_class, sizeof(zval *), NULL); SUHOSIN_G(execution_depth) = 0; if (SUHOSIN_G(log_phpscript_is_safe)) { #if PHP_VERSION_ID < 50400 PG(safe_mode) = 0; #endif PG(open_basedir) = NULL; } zend_execute(new_op_array TSRMLS_CC); SUHOSIN_G(execution_depth) = orig_execution_depth; #if PHP_VERSION_ID < 50400 PG(safe_mode) = orig_safe_mode; #endif PG(open_basedir) = orig_basedir; #ifdef ZEND_ENGINE_2 destroy_op_array(new_op_array TSRMLS_CC); #else destroy_op_array(new_op_array); #endif efree(new_op_array); #ifdef ZEND_ENGINE_2 if (!EG(exception)) #endif { if (EG(return_value_ptr_ptr)) { zval_ptr_dtor(EG(return_value_ptr_ptr)); EG(return_value_ptr_ptr) = NULL; } } } else { suhosin_log(S_INTERNAL, "Unable to execute logging PHP script: %s", SUHOSIN_G(log_phpscriptname)); return; } } else { suhosin_log(S_INTERNAL, "Unable to execute logging PHP script: %s", SUHOSIN_G(log_phpscriptname)); return; } } }
static int suhosin_check_filename(char *s, int len TSRMLS_DC) { char fname[MAXPATHLEN+1]; char *t, *h, *h2, *index, *e; int tlen, i, count=0; uint indexlen; ulong numindex; zend_bool isOk; /* check if filename is too long */ if (len > MAXPATHLEN) { return SUHOSIN_CODE_TYPE_LONGNAME; } memcpy(fname, s, len); fname[len] = 0; s = (char *)&fname; e = s + len; /* check if ASCIIZ attack -> not working yet (and cannot work in PHP4 + ZO) */ if (len != strlen(s)) { return SUHOSIN_CODE_TYPE_0FILE; } /* disallow uploaded files */ if (SG(rfc1867_uploaded_files)) { if (zend_hash_exists(SG(rfc1867_uploaded_files), (char *) s, e-s+1)) { return SUHOSIN_CODE_TYPE_UPLOADED; } } /* count number of directory traversals */ for (i=0; i < len-3; i++) { if (s[i] == '.' && s[i+1] == '.' && (s[i+2] == '/' || s[i+2] == '\\')) { count++; i+=2; } } if (SUHOSIN_G(executor_include_max_traversal) && SUHOSIN_G(executor_include_max_traversal)<=count) { return SUHOSIN_CODE_TYPE_MANYDOTS; } SDEBUG("xxx %08x %08x",SUHOSIN_G(include_whitelist),SUHOSIN_G(include_blacklist)); /* no black or whitelist then disallow all */ if (SUHOSIN_G(include_whitelist)==NULL && SUHOSIN_G(include_blacklist)==NULL) { /* disallow all URLs */ if (strstr(s, "://") != NULL || suhosin_strcasestr(s, "data:") != NULL) { return SUHOSIN_CODE_TYPE_BADURL; } } else /* whitelist is stronger than blacklist */ if (SUHOSIN_G(include_whitelist)) { do { isOk = 0; h = strstr(s, "://"); h2 = suhosin_strcasestr(s, "data:"); h2 = h2 == NULL ? NULL : h2 + 4; t = h = (h == NULL) ? h2 : ( (h2 == NULL) ? h : ( (h < h2) ? h : h2 ) ); if (h == NULL) break; while (t > s && (isalnum(t[-1]) || t[-1]=='_' || t[-1]=='.')) { t--; } tlen = e-t; zend_hash_internal_pointer_reset(SUHOSIN_G(include_whitelist)); do { int r = zend_hash_get_current_key_ex(SUHOSIN_G(include_whitelist), &index, &indexlen, &numindex, 0, NULL); if (r==HASH_KEY_NON_EXISTANT) { break; } if (r==HASH_KEY_IS_STRING) { if (h-t <= indexlen-1 && tlen>=indexlen-1) { if (strncasecmp(t, index, indexlen-1)==0) { isOk = 1; break; } } } zend_hash_move_forward(SUHOSIN_G(include_whitelist)); } while (1); /* not found in whitelist */ if (!isOk) { return SUHOSIN_CODE_TYPE_BADURL; } s = h + 1; } while (1); } else { do { int tlen; h = strstr(s, "://"); h2 = suhosin_strcasestr(s, "data:"); h2 = h2 == NULL ? NULL : h2 + 4; t = h = (h == NULL) ? h2 : ( (h2 == NULL) ? h : ( (h < h2) ? h : h2 ) ); if (h == NULL) break; while (t > s && (isalnum(t[-1]) || t[-1]=='_' || t[-1]=='.')) { t--; } tlen = e-t; zend_hash_internal_pointer_reset(SUHOSIN_G(include_blacklist)); do { int r = zend_hash_get_current_key_ex(SUHOSIN_G(include_blacklist), &index, &indexlen, &numindex, 0, NULL); if (r==HASH_KEY_NON_EXISTANT) { break; } if (r==HASH_KEY_IS_STRING) { if (h-t <= indexlen-1 && tlen>=indexlen-1) { if (strncasecmp(t, index, indexlen-1)==0) { return SUHOSIN_CODE_TYPE_BLACKURL; } } } zend_hash_move_forward(SUHOSIN_G(include_blacklist)); } while (1); s = h + 1; } while (1); } /* disallow writable files */ if (!SUHOSIN_G(executor_include_allow_writable_files)) { /* protection against *REMOTE* attacks, potential race condition of access() is irrelevant */ if (access(s, W_OK) == 0) { return SUHOSIN_CODE_TYPE_WRITABLE; } } return SUHOSIN_CODE_TYPE_GOODFILE; }
static ZEND_INI_MH(OnUpdateSuhosin_perdir) { char *tmp; if (SUHOSIN_G(perdir)) { pefree(SUHOSIN_G(perdir), 1); } SUHOSIN_G(perdir) = NULL; /* Initialize the perdir flags */ SUHOSIN_G(log_perdir) = 0; SUHOSIN_G(exec_perdir) = 0; SUHOSIN_G(get_perdir) = 0; SUHOSIN_G(cookie_perdir) = 0; SUHOSIN_G(post_perdir) = 0; SUHOSIN_G(request_perdir) = 0; SUHOSIN_G(sql_perdir) = 0; SUHOSIN_G(upload_perdir) = 0; SUHOSIN_G(misc_perdir) = 0; if (new_value == NULL) { return SUCCESS; } tmp = SUHOSIN_G(perdir) = pestrdup(new_value,1); /* trim the whitespace */ while (isspace(*tmp)) tmp++; /* should we deactivate perdir completely? */ if (*tmp == 0 || *tmp == '0') { return SUCCESS; } /* no deactivation so check the flags */ while (*tmp) { switch (*tmp) { case 'l': case 'L': SUHOSIN_G(log_perdir) = 1; break; case 'e': case 'E': SUHOSIN_G(exec_perdir) = 1; break; case 'g': case 'G': SUHOSIN_G(get_perdir) = 1; break; case 'c': case 'C': SUHOSIN_G(cookie_perdir) = 1; break; case 'p': case 'P': SUHOSIN_G(post_perdir) = 1; break; case 'r': case 'R': SUHOSIN_G(request_perdir) = 1; break; case 's': case 'S': SUHOSIN_G(sql_perdir) = 1; break; case 'u': case 'U': SUHOSIN_G(upload_perdir) = 1; break; case 'm': case 'M': SUHOSIN_G(misc_perdir) = 1; break; } tmp++; } return SUCCESS; }