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 *nrdels = Z_LVAL(retval);
196 } else if (Z_TYPE(retval) == IS_TRUE) {
197 /* This is for older API compatibility */
198 *nrdels = 1;
199 } else {
200 /* Anything else is some kind of error */
201 *nrdels = -1; // Error
202 }
203 return *nrdels;
204 }
205
PS_CREATE_SID_FUNC(user)206 PS_CREATE_SID_FUNC(user)
207 {
208 /* maintain backwards compatibility */
209 if (!Z_ISUNDEF(PSF(create_sid))) {
210 zend_string *id = NULL;
211 zval retval;
212
213 ps_call_handler(&PSF(create_sid), 0, NULL, &retval);
214
215 if (!Z_ISUNDEF(retval)) {
216 if (Z_TYPE(retval) == IS_STRING) {
217 id = zend_string_copy(Z_STR(retval));
218 }
219 zval_ptr_dtor(&retval);
220 } else {
221 zend_throw_error(NULL, "No session id returned by function");
222 return NULL;
223 }
224
225 if (!id) {
226 zend_throw_error(NULL, "Session id must be a string");
227 return NULL;
228 }
229
230 return id;
231 }
232
233 /* function as defined by PS_MOD */
234 return php_session_create_id(mod_data);
235 }
236
PS_VALIDATE_SID_FUNC(user)237 PS_VALIDATE_SID_FUNC(user)
238 {
239 /* maintain backwards compatibility */
240 if (!Z_ISUNDEF(PSF(validate_sid))) {
241 zval args[1];
242 STDVARS;
243
244 ZVAL_STR_COPY(&args[0], key);
245
246 ps_call_handler(&PSF(validate_sid), 1, args, &retval);
247
248 FINISH;
249 }
250
251 /* dummy function defined by PS_MOD */
252 return php_session_validate_sid(mod_data, key);
253 }
254
PS_UPDATE_TIMESTAMP_FUNC(user)255 PS_UPDATE_TIMESTAMP_FUNC(user)
256 {
257 zval args[2];
258 STDVARS;
259
260 ZVAL_STR_COPY(&args[0], key);
261 ZVAL_STR_COPY(&args[1], val);
262
263 /* maintain backwards compatibility */
264 if (!Z_ISUNDEF(PSF(update_timestamp))) {
265 ps_call_handler(&PSF(update_timestamp), 2, args, &retval);
266 } else {
267 ps_call_handler(&PSF(write), 2, args, &retval);
268 }
269
270 FINISH;
271 }
272
273 /*
274 * Local variables:
275 * tab-width: 4
276 * c-basic-offset: 4
277 * End:
278 * vim600: sw=4 ts=4 fdm=marker
279 * vim<600: sw=4 ts=4
280 */
281