xref: /PHP-7.4/ext/session/mod_user.c (revision a6d21963)
1b7a7b1a6SStanislav Malyshev /*
255272d3dSSascha Schumann    +----------------------------------------------------------------------+
3d0cb7153SJohannes Schlüter    | PHP Version 7                                                        |
455272d3dSSascha Schumann    +----------------------------------------------------------------------+
57a7ec01aSXinchen Hui    | Copyright (c) The PHP Group                                          |
655272d3dSSascha Schumann    +----------------------------------------------------------------------+
75bd93221Sfoobar    | This source file is subject to version 3.01 of the PHP license,      |
855272d3dSSascha Schumann    | that is bundled with this package in the file LICENSE, and is        |
9f68c7ff2SJames Cox    | available through the world-wide-web at the following url:           |
105bd93221Sfoobar    | http://www.php.net/license/3_01.txt                                  |
1155272d3dSSascha Schumann    | If you did not receive a copy of the PHP license and are unable to   |
1255272d3dSSascha Schumann    | obtain it through the world-wide-web, please send a note to          |
1355272d3dSSascha Schumann    | license@php.net so we can mail you a copy immediately.               |
1455272d3dSSascha Schumann    +----------------------------------------------------------------------+
1590613d22SSebastian Bergmann    | Author: Sascha Schumann <sascha@schumann.cx>                         |
1655272d3dSSascha Schumann    +----------------------------------------------------------------------+
1755272d3dSSascha Schumann  */
1855272d3dSSascha Schumann 
199c558821SRasmus Lerdorf #include "php.h"
209c558821SRasmus Lerdorf #include "php_session.h"
2155272d3dSSascha Schumann #include "mod_user.h"
2255272d3dSSascha Schumann 
2355272d3dSSascha Schumann const ps_module ps_mod_user = {
2455272d3dSSascha Schumann 	PS_MOD_UPDATE_TIMESTAMP(user)
2555272d3dSSascha Schumann };
26e6c8640aSYasuo Ohgaki 
2755272d3dSSascha Schumann 
ps_call_handler(zval * func,int argc,zval * argv,zval * retval)2855272d3dSSascha Schumann static void ps_call_handler(zval *func, int argc, zval *argv, zval *retval)
293647fc6fSXinchen Hui {
30bdeb220fSAnatol Belski 	int i;
3155272d3dSSascha Schumann 	if (PS(in_save_handler)) {
3255272d3dSSascha Schumann 		PS(in_save_handler) = 0;
333d6e9223SYasuo Ohgaki 		ZVAL_UNDEF(retval);
343d6e9223SYasuo Ohgaki 		php_error_docref(NULL, E_WARNING, "Cannot call session save handler in a recursive manner");
353d6e9223SYasuo Ohgaki 		return;
36d990c54cSYasuo Ohgaki 	}
373d6e9223SYasuo Ohgaki 	PS(in_save_handler) = 1;
383d6e9223SYasuo Ohgaki 	if (call_user_function(NULL, NULL, func, retval, argc, argv) == FAILURE) {
393d6e9223SYasuo Ohgaki 		zval_ptr_dtor(retval);
40bdeb220fSAnatol Belski 		ZVAL_UNDEF(retval);
41fa2e7ba0SXinchen Hui 	} else if (Z_ISUNDEF_P(retval)) {
42fa2e7ba0SXinchen Hui 		ZVAL_NULL(retval);
43d8651fbeSXinchen Hui 	}
44fa2e7ba0SXinchen Hui 	PS(in_save_handler) = 0;
45fa2e7ba0SXinchen Hui 	for (i = 0; i < argc; i++) {
463d6e9223SYasuo Ohgaki 		zval_ptr_dtor(&argv[i]);
4712d3e3d7SSascha Schumann 	}
4824c49a21SSascha Schumann }
4955272d3dSSascha Schumann 
5055272d3dSSascha Schumann #define STDVARS								\
5155272d3dSSascha Schumann 	zval retval;							\
5247cfae87SArpad Ray 	int ret = FAILURE
533647fc6fSXinchen Hui 
543e99d5ccSGwynne Raskind #define PSF(a) PS(mod_user_names).name.ps_##a
553e99d5ccSGwynne Raskind 
563e99d5ccSGwynne Raskind #define FINISH \
5755272d3dSSascha Schumann 	if (Z_TYPE(retval) != IS_UNDEF) { \
582d9885c8SSara Golemon 		if (Z_TYPE(retval) == IS_TRUE) { \
59bce6a36cSDmitry Stogov 			ret = SUCCESS; \
60bce6a36cSDmitry Stogov 		} else if (Z_TYPE(retval) == IS_FALSE) { \
61bce6a36cSDmitry Stogov 			ret = FAILURE; \
62bce6a36cSDmitry Stogov         }  else if ((Z_TYPE(retval) == IS_LONG) && (Z_LVAL(retval) == -1)) { \
63bce6a36cSDmitry Stogov 			/* BC for clever users - Deprecate me */ \
64c3e3c98eSAnatol Belski 			ret = FAILURE; \
652d9885c8SSara Golemon 		} else if ((Z_TYPE(retval) == IS_LONG) && (Z_LVAL(retval) == 0)) { \
662d9885c8SSara Golemon 			/* BC for clever users - Deprecate me */ \
67c3e3c98eSAnatol Belski 			ret = SUCCESS; \
682d9885c8SSara Golemon 		} else { \
692d9885c8SSara Golemon 			if (!EG(exception)) { \
702d9885c8SSara Golemon 				php_error_docref(NULL, E_WARNING, \
717c248975SSara Golemon 				                 "Session callback expects true/false return value"); \
72bdeb220fSAnatol Belski 			} \
737c248975SSara Golemon 			ret = FAILURE; \
747c248975SSara Golemon 			zval_ptr_dtor(&retval); \
752d9885c8SSara Golemon 		} \
76bce6a36cSDmitry Stogov 	} \
772d9885c8SSara Golemon 	return ret
782d9885c8SSara Golemon 
PS_OPEN_FUNC(user)7955272d3dSSascha Schumann PS_OPEN_FUNC(user)
8055272d3dSSascha Schumann {
8155272d3dSSascha Schumann 	zval args[2];
8255272d3dSSascha Schumann 	STDVARS;
833647fc6fSXinchen Hui 
8447cfae87SArpad Ray 	if (Z_ISUNDEF(PSF(open))) {
85b7a7b1a6SStanislav Malyshev 		php_error_docref(NULL, E_WARNING,
86d8651fbeSXinchen Hui 			"user session functions not defined");
87bdeb220fSAnatol Belski 
882cb82027SFelipe Pena 		return FAILURE;
89b7a7b1a6SStanislav Malyshev 	}
902cb82027SFelipe Pena 
912cb82027SFelipe Pena 	ZVAL_STRING(&args[0], (char*)save_path);
929ece649fSJani Taskinen 	ZVAL_STRING(&args[1], (char*)session_name);
937f52978cSYasuo Ohgaki 
947f52978cSYasuo Ohgaki 	zend_try {
959ece649fSJani Taskinen 		ps_call_handler(&PSF(open), 2, args, &retval);
96bfb9307bSYasuo Ohgaki 	} zend_catch {
9734ff7bbeSYasuo Ohgaki 		PS(session_status) = php_session_none;
98bfb9307bSYasuo Ohgaki 		if (!Z_ISUNDEF(retval)) {
99bfb9307bSYasuo Ohgaki 			zval_ptr_dtor(&retval);
10034ff7bbeSYasuo Ohgaki 		}
101bfb9307bSYasuo Ohgaki 		zend_bailout();
102bfb9307bSYasuo Ohgaki 	} zend_end_try();
103bfb9307bSYasuo Ohgaki 
104bfb9307bSYasuo Ohgaki 	PS(mod_user_implemented) = 1;
105bfb9307bSYasuo Ohgaki 
10647cfae87SArpad Ray 	FINISH;
1079ece649fSJani Taskinen }
10855272d3dSSascha Schumann 
PS_CLOSE_FUNC(user)10955272d3dSSascha Schumann PS_CLOSE_FUNC(user)
11055272d3dSSascha Schumann {
11155272d3dSSascha Schumann 	zend_bool bailout = 0;
11255272d3dSSascha Schumann 	STDVARS;
113da3660a4SXinchen Hui 
11447cfae87SArpad Ray 	if (!PS(mod_user_implemented)) {
11555272d3dSSascha Schumann 		/* already closed */
11647cfae87SArpad Ray 		return SUCCESS;
11747cfae87SArpad Ray 	}
11847cfae87SArpad Ray 
11947cfae87SArpad Ray 	zend_try {
12055272d3dSSascha Schumann 		ps_call_handler(&PSF(close), 0, NULL, &retval);
121da3660a4SXinchen Hui 	} zend_catch {
122bdeb220fSAnatol Belski 		bailout = 1;
123da3660a4SXinchen Hui 	} zend_end_try();
124da3660a4SXinchen Hui 
125da3660a4SXinchen Hui 	PS(mod_user_implemented) = 0;
126da3660a4SXinchen Hui 
1271a527397SXinchen Hui 	if (bailout) {
1281a527397SXinchen Hui 		if (!Z_ISUNDEF(retval)) {
129da3660a4SXinchen Hui 			zval_ptr_dtor(&retval);
130d8651fbeSXinchen Hui 		}
131da3660a4SXinchen Hui 		zend_bailout();
132da3660a4SXinchen Hui 	}
133da3660a4SXinchen Hui 
134da3660a4SXinchen Hui 	FINISH;
135da3660a4SXinchen Hui }
13655272d3dSSascha Schumann 
PS_READ_FUNC(user)13755272d3dSSascha Schumann PS_READ_FUNC(user)
13855272d3dSSascha Schumann {
13955272d3dSSascha Schumann 	zval args[1];
14055272d3dSSascha Schumann 	STDVARS;
1413647fc6fSXinchen Hui 
14255272d3dSSascha Schumann 	ZVAL_STR_COPY(&args[0], key);
14355272d3dSSascha Schumann 
1447f52978cSYasuo Ohgaki 	ps_call_handler(&PSF(read), 1, args, &retval);
14555272d3dSSascha Schumann 
146bdeb220fSAnatol Belski 	if (!Z_ISUNDEF(retval)) {
1479ece649fSJani Taskinen 		if (Z_TYPE(retval) == IS_STRING) {
148d8651fbeSXinchen Hui 			*val = zend_string_copy(Z_STR(retval));
1493647fc6fSXinchen Hui 			ret = SUCCESS;
150c3e3c98eSAnatol Belski 		}
15155272d3dSSascha Schumann 		zval_ptr_dtor(&retval);
15255272d3dSSascha Schumann 	}
15324c49a21SSascha Schumann 
15455272d3dSSascha Schumann 	return ret;
15555272d3dSSascha Schumann }
15655272d3dSSascha Schumann 
PS_WRITE_FUNC(user)15755272d3dSSascha Schumann PS_WRITE_FUNC(user)
15855272d3dSSascha Schumann {
15955272d3dSSascha Schumann 	zval args[2];
16055272d3dSSascha Schumann 	STDVARS;
1613647fc6fSXinchen Hui 
16255272d3dSSascha Schumann 	ZVAL_STR_COPY(&args[0], key);
1639ece649fSJani Taskinen 	ZVAL_STR_COPY(&args[1], val);
1647f52978cSYasuo Ohgaki 
1657f52978cSYasuo Ohgaki 	ps_call_handler(&PSF(write), 2, args, &retval);
16655272d3dSSascha Schumann 
167bdeb220fSAnatol Belski 	FINISH;
16855272d3dSSascha Schumann }
16955272d3dSSascha Schumann 
PS_DESTROY_FUNC(user)17055272d3dSSascha Schumann PS_DESTROY_FUNC(user)
17155272d3dSSascha Schumann {
17255272d3dSSascha Schumann 	zval args[1];
17355272d3dSSascha Schumann 	STDVARS;
1743647fc6fSXinchen Hui 
17555272d3dSSascha Schumann 	ZVAL_STR_COPY(&args[0], key);
17655272d3dSSascha Schumann 
1777f52978cSYasuo Ohgaki 	ps_call_handler(&PSF(destroy), 1, args, &retval);
17855272d3dSSascha Schumann 
179bdeb220fSAnatol Belski 	FINISH;
18055272d3dSSascha Schumann }
18155272d3dSSascha Schumann 
PS_GC_FUNC(user)18255272d3dSSascha Schumann PS_GC_FUNC(user)
18355272d3dSSascha Schumann {
18455272d3dSSascha Schumann 	zval args[1];
18555272d3dSSascha Schumann 	zval retval;
1863647fc6fSXinchen Hui 
187a4a2f66eSYasuo Ohgaki 	ZVAL_LONG(&args[0], maxlifetime);
18855272d3dSSascha Schumann 
1897f52978cSYasuo Ohgaki 	ps_call_handler(&PSF(gc), 1, args, &retval);
19055272d3dSSascha Schumann 
191bdeb220fSAnatol Belski 	if (Z_TYPE(retval) == IS_LONG) {
19255272d3dSSascha Schumann 		*nrdels = Z_LVAL(retval);
193a4a2f66eSYasuo Ohgaki 	} else if (Z_TYPE(retval) == IS_TRUE) {
194a4a2f66eSYasuo Ohgaki 		/* This is for older API compatibility */
195*a6d21963SBrent Shaffer 		*nrdels = 1;
196*a6d21963SBrent Shaffer 	} else {
197*a6d21963SBrent Shaffer 		/* Anything else is some kind of error */
198*a6d21963SBrent Shaffer 		*nrdels = -1; // Error
199*a6d21963SBrent Shaffer 	}
200*a6d21963SBrent Shaffer 	return *nrdels;
201*a6d21963SBrent Shaffer }
202a4a2f66eSYasuo Ohgaki 
PS_CREATE_SID_FUNC(user)203*a6d21963SBrent Shaffer PS_CREATE_SID_FUNC(user)
20455272d3dSSascha Schumann {
2059c558821SRasmus Lerdorf 	/* maintain backwards compatibility */
20659cf3a24SLeigh 	if (!Z_ISUNDEF(PSF(create_sid))) {
20759cf3a24SLeigh 		zend_string *id = NULL;
20859cf3a24SLeigh 		zval retval;
209d8651fbeSXinchen Hui 
2103647fc6fSXinchen Hui 		ps_call_handler(&PSF(create_sid), 0, NULL, &retval);
2113647fc6fSXinchen Hui 
21259cf3a24SLeigh 		if (!Z_ISUNDEF(retval)) {
213bdeb220fSAnatol Belski 			if (Z_TYPE(retval) == IS_STRING) {
21459cf3a24SLeigh 				id = zend_string_copy(Z_STR(retval));
215d8651fbeSXinchen Hui 			}
2163647fc6fSXinchen Hui 			zval_ptr_dtor(&retval);
217c3e3c98eSAnatol Belski 		} else {
21859cf3a24SLeigh 			zend_throw_error(NULL, "No session id returned by function");
21959cf3a24SLeigh 			return NULL;
2203647fc6fSXinchen Hui 		}
221771e5cc2SAaron Piotrowski 
22259cf3a24SLeigh 		if (!id) {
22359cf3a24SLeigh 			zend_throw_error(NULL, "Session id must be a string");
22459cf3a24SLeigh 			return NULL;
22559cf3a24SLeigh 		}
226771e5cc2SAaron Piotrowski 
22759cf3a24SLeigh 		return id;
22859cf3a24SLeigh 	}
23059cf3a24SLeigh 	/* function as defined by PS_MOD */
23159cf3a24SLeigh 	return php_session_create_id(mod_data);
23259cf3a24SLeigh }
PS_VALIDATE_SID_FUNC(user)234bdeb220fSAnatol Belski PS_VALIDATE_SID_FUNC(user)
23559cf3a24SLeigh {
23659cf3a24SLeigh 	/* maintain backwards compatibility */
237e6c8640aSYasuo Ohgaki 	if (!Z_ISUNDEF(PSF(validate_sid))) {
238e6c8640aSYasuo Ohgaki 		zval args[1];
239e6c8640aSYasuo Ohgaki 		STDVARS;
240e6c8640aSYasuo Ohgaki 
241e6c8640aSYasuo Ohgaki 		ZVAL_STR_COPY(&args[0], key);
242e6c8640aSYasuo Ohgaki 
243e6c8640aSYasuo Ohgaki 		ps_call_handler(&PSF(validate_sid), 1, args, &retval);
2447f52978cSYasuo Ohgaki 
245e6c8640aSYasuo Ohgaki 		FINISH;
246e6c8640aSYasuo Ohgaki 	}
247e6c8640aSYasuo Ohgaki 
248e6c8640aSYasuo Ohgaki 	/* dummy function defined by PS_MOD */
249e6c8640aSYasuo Ohgaki 	return php_session_validate_sid(mod_data, key);
250e6c8640aSYasuo Ohgaki }
251e6c8640aSYasuo Ohgaki 
253e6c8640aSYasuo Ohgaki {
254e6c8640aSYasuo Ohgaki 	zval args[2];
255e6c8640aSYasuo Ohgaki 	STDVARS;
256e6c8640aSYasuo Ohgaki 
257e6c8640aSYasuo Ohgaki 	ZVAL_STR_COPY(&args[0], key);
258e6c8640aSYasuo Ohgaki 	ZVAL_STR_COPY(&args[1], val);
259e6c8640aSYasuo Ohgaki 
2607f52978cSYasuo Ohgaki 	/* maintain backwards compatibility */
2617f52978cSYasuo Ohgaki 	if (!Z_ISUNDEF(PSF(update_timestamp))) {
262e6c8640aSYasuo Ohgaki 		ps_call_handler(&PSF(update_timestamp), 2, args, &retval);
263e6c8640aSYasuo Ohgaki 	} else {
264e6c8640aSYasuo Ohgaki 		ps_call_handler(&PSF(write), 2, args, &retval);
265e6c8640aSYasuo Ohgaki 	}
266e6c8640aSYasuo Ohgaki 
267e6c8640aSYasuo Ohgaki 	FINISH;
268e6c8640aSYasuo Ohgaki }
269e6c8640aSYasuo Ohgaki