1 /*
2 +----------------------------------------------------------------------+
3 | PHP Version 7 |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 1997-2018 The PHP Group |
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 3.01 of the PHP license, |
8 | that is bundled with this package in the file LICENSE, and is |
9 | available through the world-wide-web at the following url: |
10 | http://www.php.net/license/3_01.txt |
11 | If you did not receive a copy of the PHP license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@php.net so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
15 | Author: Sascha Schumann <sascha@schumann.cx> |
16 +----------------------------------------------------------------------+
17 */
18
19 /* $Id$ */
20
21 #include "php.h"
22 #include "php_session.h"
23 #include "mod_user.h"
24
25 ps_module ps_mod_user = {
26 PS_MOD_UPDATE_TIMESTAMP(user)
27 };
28
29
ps_call_handler(zval * func,int argc,zval * argv,zval * retval)30 static void ps_call_handler(zval *func, int argc, zval *argv, zval *retval)
31 {
32 int i;
33 if (PS(in_save_handler)) {
34 PS(in_save_handler) = 0;
35 ZVAL_UNDEF(retval);
36 php_error_docref(NULL, E_WARNING, "Cannot call session save handler in a recursive manner");
37 return;
38 }
39 PS(in_save_handler) = 1;
40 if (call_user_function(EG(function_table), NULL, func, retval, argc, argv) == FAILURE) {
41 zval_ptr_dtor(retval);
42 ZVAL_UNDEF(retval);
43 } else if (Z_ISUNDEF_P(retval)) {
44 ZVAL_NULL(retval);
45 }
46 PS(in_save_handler) = 0;
47 for (i = 0; i < argc; i++) {
48 zval_ptr_dtor(&argv[i]);
49 }
50 }
51
52 #define STDVARS \
53 zval retval; \
54 int ret = FAILURE
55
56 #define PSF(a) PS(mod_user_names).name.ps_##a
57
58 #define FINISH \
59 if (Z_TYPE(retval) != IS_UNDEF) { \
60 if (Z_TYPE(retval) == IS_TRUE) { \
61 ret = SUCCESS; \
62 } else if (Z_TYPE(retval) == IS_FALSE) { \
63 ret = FAILURE; \
64 } else if ((Z_TYPE(retval) == IS_LONG) && (Z_LVAL(retval) == -1)) { \
65 /* BC for clever users - Deprecate me */ \
66 ret = FAILURE; \
67 } else if ((Z_TYPE(retval) == IS_LONG) && (Z_LVAL(retval) == 0)) { \
68 /* BC for clever users - Deprecate me */ \
69 ret = SUCCESS; \
70 } else { \
71 if (!EG(exception)) { \
72 php_error_docref(NULL, E_WARNING, \
73 "Session callback expects true/false return value"); \
74 } \
75 ret = FAILURE; \
76 zval_ptr_dtor(&retval); \
77 } \
78 } \
79 return ret
80
PS_OPEN_FUNC(user)81 PS_OPEN_FUNC(user)
82 {
83 zval args[2];
84 STDVARS;
85
86 if (Z_ISUNDEF(PSF(open))) {
87 php_error_docref(NULL, E_WARNING,
88 "user session functions not defined");
89
90 return FAILURE;
91 }
92
93 ZVAL_STRING(&args[0], (char*)save_path);
94 ZVAL_STRING(&args[1], (char*)session_name);
95
96 zend_try {
97 ps_call_handler(&PSF(open), 2, args, &retval);
98 } zend_catch {
99 PS(session_status) = php_session_none;
100 if (!Z_ISUNDEF(retval)) {
101 zval_ptr_dtor(&retval);
102 }
103 zend_bailout();
104 } zend_end_try();
105
106 PS(mod_user_implemented) = 1;
107
108 FINISH;
109 }
110
PS_CLOSE_FUNC(user)111 PS_CLOSE_FUNC(user)
112 {
113 zend_bool bailout = 0;
114 STDVARS;
115
116 if (!PS(mod_user_implemented)) {
117 /* already closed */
118 return SUCCESS;
119 }
120
121 zend_try {
122 ps_call_handler(&PSF(close), 0, NULL, &retval);
123 } zend_catch {
124 bailout = 1;
125 } zend_end_try();
126
127 PS(mod_user_implemented) = 0;
128
129 if (bailout) {
130 if (!Z_ISUNDEF(retval)) {
131 zval_ptr_dtor(&retval);
132 }
133 zend_bailout();
134 }
135
136 FINISH;
137 }
138
PS_READ_FUNC(user)139 PS_READ_FUNC(user)
140 {
141 zval args[1];
142 STDVARS;
143
144 ZVAL_STR_COPY(&args[0], key);
145
146 ps_call_handler(&PSF(read), 1, args, &retval);
147
148 if (!Z_ISUNDEF(retval)) {
149 if (Z_TYPE(retval) == IS_STRING) {
150 *val = zend_string_copy(Z_STR(retval));
151 ret = SUCCESS;
152 }
153 zval_ptr_dtor(&retval);
154 }
155
156 return ret;
157 }
158
PS_WRITE_FUNC(user)159 PS_WRITE_FUNC(user)
160 {
161 zval args[2];
162 STDVARS;
163
164 ZVAL_STR_COPY(&args[0], key);
165 ZVAL_STR_COPY(&args[1], val);
166
167 ps_call_handler(&PSF(write), 2, args, &retval);
168
169 FINISH;
170 }
171
PS_DESTROY_FUNC(user)172 PS_DESTROY_FUNC(user)
173 {
174 zval args[1];
175 STDVARS;
176
177 ZVAL_STR_COPY(&args[0], key);
178
179 ps_call_handler(&PSF(destroy), 1, args, &retval);
180
181 FINISH;
182 }
183
PS_GC_FUNC(user)184 PS_GC_FUNC(user)
185 {
186 zval args[1];
187 zval retval;
188
189 ZVAL_LONG(&args[0], maxlifetime);
190
191 ps_call_handler(&PSF(gc), 1, args, &retval);
192
193 if (Z_TYPE(retval) == IS_LONG) {
194 convert_to_long(&retval);
195 return Z_LVAL(retval);
196 }
197 /* This is for older API compatibility */
198 if (Z_TYPE(retval) == IS_TRUE) {
199 return 1;
200 }
201 /* Anything else is some kind of error */
202 return -1; // Error
203 }
204
PS_CREATE_SID_FUNC(user)205 PS_CREATE_SID_FUNC(user)
206 {
207 /* maintain backwards compatibility */
208 if (!Z_ISUNDEF(PSF(create_sid))) {
209 zend_string *id = NULL;
210 zval retval;
211
212 ps_call_handler(&PSF(create_sid), 0, NULL, &retval);
213
214 if (!Z_ISUNDEF(retval)) {
215 if (Z_TYPE(retval) == IS_STRING) {
216 id = zend_string_copy(Z_STR(retval));
217 }
218 zval_ptr_dtor(&retval);
219 } else {
220 zend_throw_error(NULL, "No session id returned by function");
221 return NULL;
222 }
223
224 if (!id) {
225 zend_throw_error(NULL, "Session id must be a string");
226 return NULL;
227 }
228
229 return id;
230 }
231
232 /* function as defined by PS_MOD */
233 return php_session_create_id(mod_data);
234 }
235
PS_VALIDATE_SID_FUNC(user)236 PS_VALIDATE_SID_FUNC(user)
237 {
238 /* maintain backwards compatibility */
239 if (!Z_ISUNDEF(PSF(validate_sid))) {
240 zval args[1];
241 STDVARS;
242
243 ZVAL_STR_COPY(&args[0], key);
244
245 ps_call_handler(&PSF(validate_sid), 1, args, &retval);
246
247 FINISH;
248 }
249
250 /* dummy function defined by PS_MOD */
251 return php_session_validate_sid(mod_data, key);
252 }
253
PS_UPDATE_TIMESTAMP_FUNC(user)254 PS_UPDATE_TIMESTAMP_FUNC(user)
255 {
256 zval args[2];
257 STDVARS;
258
259 ZVAL_STR_COPY(&args[0], key);
260 ZVAL_STR_COPY(&args[1], val);
261
262 /* maintain backwards compatibility */
263 if (!Z_ISUNDEF(PSF(update_timestamp))) {
264 ps_call_handler(&PSF(update_timestamp), 2, args, &retval);
265 } else {
266 ps_call_handler(&PSF(write), 2, args, &retval);
267 }
268
269 FINISH;
270 }
271
272 /*
273 * Local variables:
274 * tab-width: 4
275 * c-basic-offset: 4
276 * End:
277 * vim600: sw=4 ts=4 fdm=marker
278 * vim<600: sw=4 ts=4
279 */
280