xref: /PHP-5.5/ext/session/mod_user.c (revision 73c1be26)
1 /*
2    +----------------------------------------------------------------------+
3    | PHP Version 5                                                        |
4    +----------------------------------------------------------------------+
5    | Copyright (c) 1997-2015 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_SID(user)
27 };
28 
29 #define SESS_ZVAL_LONG(val, a)						\
30 {													\
31 	MAKE_STD_ZVAL(a);								\
32 	ZVAL_LONG(a, val);								\
33 }
34 
35 #define SESS_ZVAL_STRING(vl, a)						\
36 {													\
37 	char *__vl = vl;								\
38 	SESS_ZVAL_STRINGN(__vl, strlen(__vl), a);		\
39 }
40 
41 #define SESS_ZVAL_STRINGN(vl, ln, a)				\
42 {													\
43 	MAKE_STD_ZVAL(a);								\
44 	ZVAL_STRINGL(a, vl, ln, 1);						\
45 }
46 
ps_call_handler(zval * func,int argc,zval ** argv TSRMLS_DC)47 static zval *ps_call_handler(zval *func, int argc, zval **argv TSRMLS_DC)
48 {
49 	int i;
50 	zval *retval = NULL;
51 
52 	MAKE_STD_ZVAL(retval);
53 	if (call_user_function(EG(function_table), NULL, func, retval, argc, argv TSRMLS_CC) == FAILURE) {
54 		zval_ptr_dtor(&retval);
55 		retval = NULL;
56 	}
57 
58 	for (i = 0; i < argc; i++) {
59 		zval_ptr_dtor(&argv[i]);
60 	}
61 
62 	return retval;
63 }
64 
65 #define STDVARS								\
66 	zval *retval = NULL;					\
67 	int ret = FAILURE
68 
69 #define PSF(a) PS(mod_user_names).name.ps_##a
70 
71 #define FINISH								\
72 	if (retval) {							\
73 		convert_to_long(retval);			\
74 		ret = Z_LVAL_P(retval);				\
75 		zval_ptr_dtor(&retval);				\
76 	}										\
77 	return ret
78 
PS_OPEN_FUNC(user)79 PS_OPEN_FUNC(user)
80 {
81 	zval *args[2];
82 	STDVARS;
83 
84 	if (PSF(open) == NULL) {
85 		php_error_docref(NULL TSRMLS_CC, E_WARNING,
86 			"user session functions not defined");
87 
88 		return FAILURE;
89 	}
90 
91 	SESS_ZVAL_STRING((char*)save_path, args[0]);
92 	SESS_ZVAL_STRING((char*)session_name, args[1]);
93 
94 	retval = ps_call_handler(PSF(open), 2, args TSRMLS_CC);
95 	PS(mod_user_implemented) = 1;
96 
97 	FINISH;
98 }
99 
PS_CLOSE_FUNC(user)100 PS_CLOSE_FUNC(user)
101 {
102 	zend_bool bailout = 0;
103 	STDVARS;
104 
105 	if (!PS(mod_user_implemented)) {
106 		/* already closed */
107 		return SUCCESS;
108 	}
109 
110 	zend_try {
111 		retval = ps_call_handler(PSF(close), 0, NULL TSRMLS_CC);
112 	} zend_catch {
113 		bailout = 1;
114 	} zend_end_try();
115 
116 	PS(mod_user_implemented) = 0;
117 
118 	if (bailout) {
119 		if (retval) {
120 			zval_ptr_dtor(&retval);
121 		}
122 		zend_bailout();
123 	}
124 
125 	FINISH;
126 }
127 
PS_READ_FUNC(user)128 PS_READ_FUNC(user)
129 {
130 	zval *args[1];
131 	STDVARS;
132 
133 	SESS_ZVAL_STRING((char*)key, args[0]);
134 
135 	retval = ps_call_handler(PSF(read), 1, args TSRMLS_CC);
136 
137 	if (retval) {
138 		if (Z_TYPE_P(retval) == IS_STRING) {
139 			*val = estrndup(Z_STRVAL_P(retval), Z_STRLEN_P(retval));
140 			*vallen = Z_STRLEN_P(retval);
141 			ret = SUCCESS;
142 		}
143 		zval_ptr_dtor(&retval);
144 	}
145 
146 	return ret;
147 }
148 
PS_WRITE_FUNC(user)149 PS_WRITE_FUNC(user)
150 {
151 	zval *args[2];
152 	STDVARS;
153 
154 	SESS_ZVAL_STRING((char*)key, args[0]);
155 	SESS_ZVAL_STRINGN((char*)val, vallen, args[1]);
156 
157 	retval = ps_call_handler(PSF(write), 2, args TSRMLS_CC);
158 
159 	FINISH;
160 }
161 
PS_DESTROY_FUNC(user)162 PS_DESTROY_FUNC(user)
163 {
164 	zval *args[1];
165 	STDVARS;
166 
167 	SESS_ZVAL_STRING((char*)key, args[0]);
168 
169 	retval = ps_call_handler(PSF(destroy), 1, args TSRMLS_CC);
170 
171 	FINISH;
172 }
173 
PS_GC_FUNC(user)174 PS_GC_FUNC(user)
175 {
176 	zval *args[1];
177 	STDVARS;
178 
179 	SESS_ZVAL_LONG(maxlifetime, args[0]);
180 
181 	retval = ps_call_handler(PSF(gc), 1, args TSRMLS_CC);
182 
183 	FINISH;
184 }
185 
PS_CREATE_SID_FUNC(user)186 PS_CREATE_SID_FUNC(user)
187 {
188 	/* maintain backwards compatibility */
189 	if (PSF(create_sid) != NULL) {
190 		char *id = NULL;
191 		zval *retval = NULL;
192 
193 		retval = ps_call_handler(PSF(create_sid), 0, NULL TSRMLS_CC);
194 
195 		if (retval) {
196 			if (Z_TYPE_P(retval) == IS_STRING) {
197 				id = estrndup(Z_STRVAL_P(retval), Z_STRLEN_P(retval));
198 			}
199 			zval_ptr_dtor(&retval);
200 		}
201 		else {
202 			php_error_docref(NULL TSRMLS_CC, E_ERROR, "No session id returned by function");
203 			return NULL;
204 		}
205 
206 		if (!id) {
207 			php_error_docref(NULL TSRMLS_CC, E_ERROR, "Session id must be a string");
208 			return NULL;
209 		}
210 
211 		return id;
212 	}
213 
214 	/* function as defined by PS_MOD */
215 	return php_session_create_id(mod_data, newlen TSRMLS_CC);
216 }
217 
218 /*
219  * Local variables:
220  * tab-width: 4
221  * c-basic-offset: 4
222  * End:
223  * vim600: sw=4 ts=4 fdm=marker
224  * vim<600: sw=4 ts=4
225  */
226