mod_user.c 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268
  1. /*
  2. +----------------------------------------------------------------------+
  3. | Copyright (c) The PHP Group |
  4. +----------------------------------------------------------------------+
  5. | This source file is subject to version 3.01 of the PHP license, |
  6. | that is bundled with this package in the file LICENSE, and is |
  7. | available through the world-wide-web at the following url: |
  8. | https://www.php.net/license/3_01.txt |
  9. | If you did not receive a copy of the PHP license and are unable to |
  10. | obtain it through the world-wide-web, please send a note to |
  11. | license@php.net so we can mail you a copy immediately. |
  12. +----------------------------------------------------------------------+
  13. | Author: Sascha Schumann <sascha@schumann.cx> |
  14. +----------------------------------------------------------------------+
  15. */
  16. #include "php.h"
  17. #include "php_session.h"
  18. #include "mod_user.h"
  19. const ps_module ps_mod_user = {
  20. PS_MOD_UPDATE_TIMESTAMP(user)
  21. };
  22. static void ps_call_handler(zval *func, int argc, zval *argv, zval *retval)
  23. {
  24. int i;
  25. if (PS(in_save_handler)) {
  26. PS(in_save_handler) = 0;
  27. ZVAL_UNDEF(retval);
  28. php_error_docref(NULL, E_WARNING, "Cannot call session save handler in a recursive manner");
  29. return;
  30. }
  31. PS(in_save_handler) = 1;
  32. if (call_user_function(NULL, NULL, func, retval, argc, argv) == FAILURE) {
  33. zval_ptr_dtor(retval);
  34. ZVAL_UNDEF(retval);
  35. } else if (Z_ISUNDEF_P(retval)) {
  36. ZVAL_NULL(retval);
  37. }
  38. PS(in_save_handler) = 0;
  39. for (i = 0; i < argc; i++) {
  40. zval_ptr_dtor(&argv[i]);
  41. }
  42. }
  43. #define STDVARS \
  44. zval retval; \
  45. int ret = FAILURE
  46. #define PSF(a) PS(mod_user_names).name.ps_##a
  47. #define FINISH \
  48. if (Z_TYPE(retval) != IS_UNDEF) { \
  49. if (Z_TYPE(retval) == IS_TRUE) { \
  50. ret = SUCCESS; \
  51. } else if (Z_TYPE(retval) == IS_FALSE) { \
  52. ret = FAILURE; \
  53. } else if ((Z_TYPE(retval) == IS_LONG) && (Z_LVAL(retval) == -1)) { \
  54. if (!EG(exception)) { \
  55. php_error_docref(NULL, E_DEPRECATED, "Session callback must have a return value of type bool, %s returned", zend_zval_type_name(&retval)); \
  56. } \
  57. ret = FAILURE; \
  58. } else if ((Z_TYPE(retval) == IS_LONG) && (Z_LVAL(retval) == 0)) { \
  59. if (!EG(exception)) { \
  60. php_error_docref(NULL, E_DEPRECATED, "Session callback must have a return value of type bool, %s returned", zend_zval_type_name(&retval)); \
  61. } \
  62. ret = SUCCESS; \
  63. } else { \
  64. if (!EG(exception)) { \
  65. zend_type_error("Session callback must have a return value of type bool, %s returned", zend_zval_type_name(&retval)); \
  66. } \
  67. ret = FAILURE; \
  68. zval_ptr_dtor(&retval); \
  69. } \
  70. } \
  71. return ret
  72. PS_OPEN_FUNC(user)
  73. {
  74. zval args[2];
  75. STDVARS;
  76. if (Z_ISUNDEF(PSF(open))) {
  77. php_error_docref(NULL, E_WARNING, "User session functions are 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. 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. *nrdels = Z_LVAL(retval);
  156. } else if (Z_TYPE(retval) == IS_TRUE) {
  157. /* This is for older API compatibility */
  158. *nrdels = 1;
  159. } else {
  160. /* Anything else is some kind of error */
  161. *nrdels = -1; // Error
  162. }
  163. return *nrdels;
  164. }
  165. PS_CREATE_SID_FUNC(user)
  166. {
  167. /* maintain backwards compatibility */
  168. if (!Z_ISUNDEF(PSF(create_sid))) {
  169. zend_string *id = NULL;
  170. zval retval;
  171. ps_call_handler(&PSF(create_sid), 0, NULL, &retval);
  172. if (!Z_ISUNDEF(retval)) {
  173. if (Z_TYPE(retval) == IS_STRING) {
  174. id = zend_string_copy(Z_STR(retval));
  175. }
  176. zval_ptr_dtor(&retval);
  177. } else {
  178. zend_throw_error(NULL, "No session id returned by function");
  179. return NULL;
  180. }
  181. if (!id) {
  182. zend_throw_error(NULL, "Session id must be a string");
  183. return NULL;
  184. }
  185. return id;
  186. }
  187. /* function as defined by PS_MOD */
  188. return php_session_create_id(mod_data);
  189. }
  190. PS_VALIDATE_SID_FUNC(user)
  191. {
  192. /* maintain backwards compatibility */
  193. if (!Z_ISUNDEF(PSF(validate_sid))) {
  194. zval args[1];
  195. STDVARS;
  196. ZVAL_STR_COPY(&args[0], key);
  197. ps_call_handler(&PSF(validate_sid), 1, args, &retval);
  198. FINISH;
  199. }
  200. /* dummy function defined by PS_MOD */
  201. return php_session_validate_sid(mod_data, key);
  202. }
  203. PS_UPDATE_TIMESTAMP_FUNC(user)
  204. {
  205. zval args[2];
  206. STDVARS;
  207. ZVAL_STR_COPY(&args[0], key);
  208. ZVAL_STR_COPY(&args[1], val);
  209. /* maintain backwards compatibility */
  210. if (!Z_ISUNDEF(PSF(update_timestamp))) {
  211. ps_call_handler(&PSF(update_timestamp), 2, args, &retval);
  212. } else {
  213. ps_call_handler(&PSF(write), 2, args, &retval);
  214. }
  215. FINISH;
  216. }