mod_user.c 5.9 KB

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