This source file includes following definitions.
- fpm_php_zend_ini_alter_master
- fpm_php_disable
- fpm_php_apply_defines_ex
- fpm_php_apply_defines
- fpm_php_set_allowed_clients
- fpm_php_set_fcgi_mgmt_vars
- fpm_php_script_filename
- fpm_php_request_uri
- fpm_php_request_method
- fpm_php_query_string
- fpm_php_auth_user
- fpm_php_content_length
- fpm_php_cleanup
- fpm_php_soft_quit
- fpm_php_init_main
- fpm_php_init_child
- fpm_php_limit_extensions
- fpm_php_get_string_from_table
1
2
3
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
146 static int fpm_php_set_fcgi_mgmt_vars(struct fpm_worker_pool_s *wp)
147 {
148 char max_workers[10 + 1];
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;
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;
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;
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
272
273 zend_is_auto_global(table, strlen(table) TSRMLS_CC);
274
275
276 if (zend_hash_find(&EG(symbol_table), table, strlen(table) + 1, (void **) &data) == SUCCESS && Z_TYPE_PP(data) == IS_ARRAY) {
277
278
279 zend_hash_internal_pointer_reset(Z_ARRVAL_PP(data));
280
281
282 while (zend_hash_get_current_data(Z_ARRVAL_PP(data), (void **) &tmp) == SUCCESS) {
283
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
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