root/sapi/fpm/fpm/fpm_php.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. fpm_php_zend_ini_alter_master
  2. fpm_php_disable
  3. fpm_php_apply_defines_ex
  4. fpm_php_apply_defines
  5. fpm_php_set_allowed_clients
  6. fpm_php_set_fcgi_mgmt_vars
  7. fpm_php_script_filename
  8. fpm_php_request_uri
  9. fpm_php_request_method
  10. fpm_php_query_string
  11. fpm_php_auth_user
  12. fpm_php_content_length
  13. fpm_php_cleanup
  14. fpm_php_soft_quit
  15. fpm_php_init_main
  16. fpm_php_init_child
  17. fpm_php_limit_extensions
  18. fpm_php_get_string_from_table

   1 
   2         /* $Id: fpm_php.c,v 1.22.2.4 2008/12/13 03:21:18 anight Exp $ */
   3         /* (c) 2007,2008 Andrei Nigmatulin */
   4 
   5 #include "fpm_config.h"
   6 
   7 #include <stdlib.h>
   8 #include <string.h>
   9 #include <stdio.h>
  10 
  11 #include "php.h"
  12 #include "php_main.h"
  13 #include "php_ini.h"
  14 #include "ext/standard/dl.h"
  15 
  16 #include "fastcgi.h"
  17 
  18 #include "fpm.h"
  19 #include "fpm_php.h"
  20 #include "fpm_cleanup.h"
  21 #include "fpm_worker_pool.h"
  22 #include "zlog.h"
  23 
  24 static char **limit_extensions = NULL;
  25 
  26 static int fpm_php_zend_ini_alter_master(char *name, int name_length, char *new_value, int new_value_length, int mode, int stage TSRMLS_DC) /* {{{ */
  27 {
  28         zend_ini_entry *ini_entry;
  29         char *duplicate;
  30 
  31         if (zend_hash_find(EG(ini_directives), name, name_length, (void **) &ini_entry) == FAILURE) {
  32                 return FAILURE;
  33         }
  34 
  35         duplicate = strdup(new_value);
  36 
  37         if (!ini_entry->on_modify
  38                         || ini_entry->on_modify(ini_entry, duplicate, new_value_length,
  39                                 ini_entry->mh_arg1, ini_entry->mh_arg2, ini_entry->mh_arg3, stage TSRMLS_CC) == SUCCESS) {
  40                 ini_entry->value = duplicate;
  41                 ini_entry->value_length = new_value_length;
  42                 ini_entry->modifiable = mode;
  43         } else {
  44                 free(duplicate);
  45         }
  46 
  47         return SUCCESS;
  48 }
  49 /* }}} */
  50 
  51 static void fpm_php_disable(char *value, int (*zend_disable)(char *, uint TSRMLS_DC) TSRMLS_DC) /* {{{ */
  52 {
  53         char *s = 0, *e = value;
  54 
  55         while (*e) {
  56                 switch (*e) {
  57                         case ' ':
  58                         case ',':
  59                                 if (s) {
  60                                         *e = '\0';
  61                                         zend_disable(s, e - s TSRMLS_CC);
  62                                         s = 0;
  63                                 }
  64                                 break;
  65                         default:
  66                                 if (!s) {
  67                                         s = e;
  68                                 }
  69                                 break;
  70                 }
  71                 e++;
  72         }
  73 
  74         if (s) {
  75                 zend_disable(s, e - s TSRMLS_CC);
  76         }
  77 }
  78 /* }}} */
  79 
  80 int fpm_php_apply_defines_ex(struct key_value_s *kv, int mode) /* {{{ */
  81 {
  82         TSRMLS_FETCH();
  83 
  84         char *name = kv->key;
  85         char *value = kv->value;
  86         int name_len = strlen(name);
  87         int value_len = strlen(value);
  88 
  89         if (!strcmp(name, "extension") && *value) {
  90                 zval zv;
  91                 php_dl(value, MODULE_PERSISTENT, &zv, 1 TSRMLS_CC);
  92                 return Z_BVAL(zv) ? 1 : -1;
  93         }
  94 
  95         if (fpm_php_zend_ini_alter_master(name, name_len+1, value, value_len, mode, PHP_INI_STAGE_ACTIVATE TSRMLS_CC) == FAILURE) {
  96                 return -1;
  97         }
  98 
  99         if (!strcmp(name, "disable_functions") && *value) {
 100                 char *v = strdup(value);
 101                 PG(disable_functions) = v;
 102                 fpm_php_disable(v, zend_disable_function TSRMLS_CC);
 103                 return 1;
 104         }
 105 
 106         if (!strcmp(name, "disable_classes") && *value) {
 107                 char *v = strdup(value);
 108                 PG(disable_classes) = v;
 109                 fpm_php_disable(v, zend_disable_class TSRMLS_CC);
 110                 return 1;
 111         }
 112 
 113         return 1;
 114 }
 115 /* }}} */
 116 
 117 static int fpm_php_apply_defines(struct fpm_worker_pool_s *wp) /* {{{ */
 118 {
 119         struct key_value_s *kv;
 120 
 121         for (kv = wp->config->php_values; kv; kv = kv->next) {
 122                 if (fpm_php_apply_defines_ex(kv, ZEND_INI_USER) == -1) {
 123                         zlog(ZLOG_ERROR, "Unable to set php_value '%s'", kv->key);
 124                 }
 125         }
 126 
 127         for (kv = wp->config->php_admin_values; kv; kv = kv->next) {
 128                 if (fpm_php_apply_defines_ex(kv, ZEND_INI_SYSTEM) == -1) {
 129                         zlog(ZLOG_ERROR, "Unable to set php_admin_value '%s'", kv->key);
 130                 }
 131         }
 132 
 133         return 0;
 134 }
 135 
 136 static int fpm_php_set_allowed_clients(struct fpm_worker_pool_s *wp) /* {{{ */
 137 {
 138         if (wp->listen_address_domain == FPM_AF_INET) {
 139                 fcgi_set_allowed_clients(wp->config->listen_allowed_clients);
 140         }
 141         return 0;
 142 }
 143 /* }}} */
 144 
 145 #if 0 /* Comment out this non used function. It could be used later. */
 146 static int fpm_php_set_fcgi_mgmt_vars(struct fpm_worker_pool_s *wp) /* {{{ */
 147 {
 148         char max_workers[10 + 1]; /* 4294967295 */
 149         int len;
 150 
 151         len = sprintf(max_workers, "%u", (unsigned int) wp->config->pm_max_children);
 152 
 153         fcgi_set_mgmt_var("FCGI_MAX_CONNS", sizeof("FCGI_MAX_CONNS")-1, max_workers, len);
 154         fcgi_set_mgmt_var("FCGI_MAX_REQS",  sizeof("FCGI_MAX_REQS")-1,  max_workers, len);
 155         return 0;
 156 }
 157 /* }}} */
 158 #endif
 159 
 160 char *fpm_php_script_filename(TSRMLS_D) /* {{{ */
 161 {
 162         return SG(request_info).path_translated;
 163 }
 164 /* }}} */
 165 
 166 char *fpm_php_request_uri(TSRMLS_D) /* {{{ */
 167 {
 168         return (char *) SG(request_info).request_uri;
 169 }
 170 /* }}} */
 171 
 172 char *fpm_php_request_method(TSRMLS_D) /* {{{ */
 173 {
 174         return (char *) SG(request_info).request_method;
 175 }
 176 /* }}} */
 177 
 178 char *fpm_php_query_string(TSRMLS_D) /* {{{ */
 179 {
 180         return SG(request_info).query_string;
 181 }
 182 /* }}} */
 183 
 184 char *fpm_php_auth_user(TSRMLS_D) /* {{{ */
 185 {
 186         return SG(request_info).auth_user;
 187 }
 188 /* }}} */
 189 
 190 size_t fpm_php_content_length(TSRMLS_D) /* {{{ */
 191 {
 192         return SG(request_info).content_length;
 193 }
 194 /* }}} */
 195 
 196 static void fpm_php_cleanup(int which, void *arg) /* {{{ */
 197 {
 198         TSRMLS_FETCH();
 199         php_module_shutdown(TSRMLS_C);
 200         sapi_shutdown();
 201 }
 202 /* }}} */
 203 
 204 void fpm_php_soft_quit() /* {{{ */
 205 {
 206         fcgi_set_in_shutdown(1);
 207 }
 208 /* }}} */
 209 
 210 int fpm_php_init_main() /* {{{ */
 211 {
 212         if (0 > fpm_cleanup_add(FPM_CLEANUP_PARENT, fpm_php_cleanup, 0)) {
 213                 return -1;
 214         }
 215         return 0;
 216 }
 217 /* }}} */
 218 
 219 int fpm_php_init_child(struct fpm_worker_pool_s *wp) /* {{{ */
 220 {
 221         if (0 > fpm_php_apply_defines(wp) ||
 222                 0 > fpm_php_set_allowed_clients(wp)) {
 223                 return -1;
 224         }
 225 
 226         if (wp->limit_extensions) {
 227                 limit_extensions = wp->limit_extensions;
 228         }
 229         return 0;
 230 }
 231 /* }}} */
 232 
 233 int fpm_php_limit_extensions(char *path) /* {{{ */
 234 {
 235         char **p;
 236         size_t path_len;
 237 
 238         if (!path || !limit_extensions) {
 239                 return 0; /* allowed by default */
 240         }
 241 
 242         p = limit_extensions;
 243         path_len = strlen(path);
 244         while (p && *p) {
 245                 size_t ext_len = strlen(*p);
 246                 if (path_len > ext_len) {
 247                         char *path_ext = path + path_len - ext_len;
 248                         if (strcmp(*p, path_ext) == 0) {
 249                                 return 0; /* allow as the extension has been found */
 250                         }
 251                 }
 252                 p++;
 253         }
 254 
 255 
 256         zlog(ZLOG_NOTICE, "Access to the script '%s' has been denied (see security.limit_extensions)", path);
 257         return 1; /* extension not found: not allowed  */
 258 }
 259 /* }}} */
 260 
 261 char* fpm_php_get_string_from_table(char *table, char *key TSRMLS_DC) /* {{{ */
 262 {
 263         zval **data, **tmp;
 264         char *string_key;
 265         uint string_len;
 266         ulong num_key;
 267         if (!table || !key) {
 268                 return NULL;
 269         }
 270 
 271         /* inspired from ext/standard/info.c */
 272 
 273         zend_is_auto_global(table, strlen(table) TSRMLS_CC);
 274 
 275         /* find the table and ensure it's an array */
 276         if (zend_hash_find(&EG(symbol_table), table, strlen(table) + 1, (void **) &data) == SUCCESS && Z_TYPE_PP(data) == IS_ARRAY) {
 277 
 278                 /* reset the internal pointer */
 279                 zend_hash_internal_pointer_reset(Z_ARRVAL_PP(data));
 280 
 281                 /* parse the array to look for our key */
 282                 while (zend_hash_get_current_data(Z_ARRVAL_PP(data), (void **) &tmp) == SUCCESS) {
 283                         /* ensure the key is a string */
 284                         if (zend_hash_get_current_key_ex(Z_ARRVAL_PP(data), &string_key, &string_len, &num_key, 0, NULL) == HASH_KEY_IS_STRING) {
 285                                 /* compare to our key */
 286                                 if (!strncmp(string_key, key, string_len)) {
 287                                         return Z_STRVAL_PP(tmp);
 288                                 }
 289                         }
 290                         zend_hash_move_forward(Z_ARRVAL_PP(data));
 291                 }
 292         }
 293 
 294         return NULL;
 295 }
 296 /* }}} */
 297 

/* [<][>][^][v][top][bottom][index][help] */