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