prestogres 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (393) hide show
  1. data/.gitignore +4 -0
  2. data/Gemfile +2 -0
  3. data/Gemfile.lock +20 -0
  4. data/LICENSE +202 -0
  5. data/NOTICE +22 -0
  6. data/README.md +217 -0
  7. data/Rakefile +13 -0
  8. data/VERSION +1 -0
  9. data/bin/prestogres +254 -0
  10. data/config/pcp.conf.sample +28 -0
  11. data/config/pgpool.conf +678 -0
  12. data/config/pool_hba.conf +84 -0
  13. data/config/pool_passwd +0 -0
  14. data/config/postgresql.conf +2 -0
  15. data/ext/.gitignore +6 -0
  16. data/ext/depend +26 -0
  17. data/ext/extconf.rb +4 -0
  18. data/ext/prestogres_config.c +12 -0
  19. data/pgpool2/.gitignore +36 -0
  20. data/pgpool2/AUTHORS +4 -0
  21. data/pgpool2/COPYING +12 -0
  22. data/pgpool2/ChangeLog +1 -0
  23. data/pgpool2/INSTALL +1 -0
  24. data/pgpool2/Makefile.am +159 -0
  25. data/pgpool2/Makefile.in +1187 -0
  26. data/pgpool2/NEWS +4960 -0
  27. data/pgpool2/README +1 -0
  28. data/pgpool2/README.euc_jp +1 -0
  29. data/pgpool2/README.online-recovery +62 -0
  30. data/pgpool2/TODO +103 -0
  31. data/pgpool2/ac_func_accept_argtypes.m4 +85 -0
  32. data/pgpool2/aclocal.m4 +1088 -0
  33. data/pgpool2/c-compiler.m4 +134 -0
  34. data/pgpool2/c-library.m4 +325 -0
  35. data/pgpool2/child.c +2097 -0
  36. data/pgpool2/config.guess +1532 -0
  37. data/pgpool2/config.h.in +332 -0
  38. data/pgpool2/config.sub +1640 -0
  39. data/pgpool2/configure +15752 -0
  40. data/pgpool2/configure.in +392 -0
  41. data/pgpool2/depcomp +522 -0
  42. data/pgpool2/doc/basebackup.sh +17 -0
  43. data/pgpool2/doc/pgpool-de.html +4220 -0
  44. data/pgpool2/doc/pgpool-en.html +5738 -0
  45. data/pgpool2/doc/pgpool-fr.html +4118 -0
  46. data/pgpool2/doc/pgpool-ja.css +198 -0
  47. data/pgpool2/doc/pgpool-ja.html +11279 -0
  48. data/pgpool2/doc/pgpool-zh_cn.html +4445 -0
  49. data/pgpool2/doc/pgpool.css +280 -0
  50. data/pgpool2/doc/pgpool_remote_start +13 -0
  51. data/pgpool2/doc/recovery.conf.sample +117 -0
  52. data/pgpool2/doc/tutorial-en.html +707 -0
  53. data/pgpool2/doc/tutorial-ja.html +422 -0
  54. data/pgpool2/doc/tutorial-memqcache-en.html +325 -0
  55. data/pgpool2/doc/tutorial-memqcache-ja.html +370 -0
  56. data/pgpool2/doc/tutorial-memqcache-zh_cn.html +322 -0
  57. data/pgpool2/doc/tutorial-watchdog-en.html +306 -0
  58. data/pgpool2/doc/tutorial-watchdog-ja.html +343 -0
  59. data/pgpool2/doc/tutorial-watchdog-zh_cn.html +301 -0
  60. data/pgpool2/doc/tutorial-zh_cn.html +537 -0
  61. data/pgpool2/doc/watchdog.png +0 -0
  62. data/pgpool2/doc/wd-en.html +236 -0
  63. data/pgpool2/doc/wd-en.jpg +0 -0
  64. data/pgpool2/doc/wd-ja.html +219 -0
  65. data/pgpool2/doc/wd-ja.jpg +0 -0
  66. data/pgpool2/doc/wd-zh_cn.html +201 -0
  67. data/pgpool2/doc/where_to_send_queries.odg +0 -0
  68. data/pgpool2/doc/where_to_send_queries.pdf +0 -0
  69. data/pgpool2/general.m4 +166 -0
  70. data/pgpool2/getopt_long.c +200 -0
  71. data/pgpool2/getopt_long.h +44 -0
  72. data/pgpool2/install-sh +251 -0
  73. data/pgpool2/ltmain.sh +8406 -0
  74. data/pgpool2/m4/libtool.m4 +7360 -0
  75. data/pgpool2/m4/ltoptions.m4 +368 -0
  76. data/pgpool2/m4/ltsugar.m4 +123 -0
  77. data/pgpool2/m4/ltversion.m4 +23 -0
  78. data/pgpool2/m4/lt~obsolete.m4 +92 -0
  79. data/pgpool2/main.c +2971 -0
  80. data/pgpool2/md5.c +444 -0
  81. data/pgpool2/md5.h +28 -0
  82. data/pgpool2/missing +360 -0
  83. data/pgpool2/mkinstalldirs +40 -0
  84. data/pgpool2/parser/Makefile.am +50 -0
  85. data/pgpool2/parser/Makefile.in +559 -0
  86. data/pgpool2/parser/copyfuncs.c +3310 -0
  87. data/pgpool2/parser/gram.c +39100 -0
  88. data/pgpool2/parser/gram.h +940 -0
  89. data/pgpool2/parser/gram.y +13408 -0
  90. data/pgpool2/parser/gramparse.h +74 -0
  91. data/pgpool2/parser/keywords.c +32 -0
  92. data/pgpool2/parser/keywords.h +39 -0
  93. data/pgpool2/parser/kwlist.h +425 -0
  94. data/pgpool2/parser/kwlookup.c +88 -0
  95. data/pgpool2/parser/list.c +1156 -0
  96. data/pgpool2/parser/makefuncs.c +518 -0
  97. data/pgpool2/parser/makefuncs.h +83 -0
  98. data/pgpool2/parser/memnodes.h +79 -0
  99. data/pgpool2/parser/nodes.c +29 -0
  100. data/pgpool2/parser/nodes.h +609 -0
  101. data/pgpool2/parser/outfuncs.c +5790 -0
  102. data/pgpool2/parser/parsenodes.h +2615 -0
  103. data/pgpool2/parser/parser.c +262 -0
  104. data/pgpool2/parser/parser.h +46 -0
  105. data/pgpool2/parser/pg_class.h +158 -0
  106. data/pgpool2/parser/pg_config_manual.h +273 -0
  107. data/pgpool2/parser/pg_list.h +352 -0
  108. data/pgpool2/parser/pg_trigger.h +147 -0
  109. data/pgpool2/parser/pg_wchar.h +492 -0
  110. data/pgpool2/parser/pool_memory.c +342 -0
  111. data/pgpool2/parser/pool_memory.h +77 -0
  112. data/pgpool2/parser/pool_parser.h +222 -0
  113. data/pgpool2/parser/pool_string.c +121 -0
  114. data/pgpool2/parser/pool_string.h +37 -0
  115. data/pgpool2/parser/primnodes.h +1280 -0
  116. data/pgpool2/parser/scan.c +4094 -0
  117. data/pgpool2/parser/scan.l +1451 -0
  118. data/pgpool2/parser/scanner.h +120 -0
  119. data/pgpool2/parser/scansup.c +221 -0
  120. data/pgpool2/parser/scansup.h +28 -0
  121. data/pgpool2/parser/snprintf.c +1102 -0
  122. data/pgpool2/parser/stringinfo.c +294 -0
  123. data/pgpool2/parser/stringinfo.h +178 -0
  124. data/pgpool2/parser/value.c +78 -0
  125. data/pgpool2/parser/value.h +62 -0
  126. data/pgpool2/parser/wchar.c +2048 -0
  127. data/pgpool2/pcp.conf.sample +28 -0
  128. data/pgpool2/pcp/Makefile.am +40 -0
  129. data/pgpool2/pcp/Makefile.in +771 -0
  130. data/pgpool2/pcp/libpcp_ext.h +250 -0
  131. data/pgpool2/pcp/md5.c +444 -0
  132. data/pgpool2/pcp/md5.h +28 -0
  133. data/pgpool2/pcp/pcp.c +1652 -0
  134. data/pgpool2/pcp/pcp.h +61 -0
  135. data/pgpool2/pcp/pcp_attach_node.c +172 -0
  136. data/pgpool2/pcp/pcp_detach_node.c +185 -0
  137. data/pgpool2/pcp/pcp_error.c +87 -0
  138. data/pgpool2/pcp/pcp_node_count.c +160 -0
  139. data/pgpool2/pcp/pcp_node_info.c +198 -0
  140. data/pgpool2/pcp/pcp_pool_status.c +166 -0
  141. data/pgpool2/pcp/pcp_proc_count.c +166 -0
  142. data/pgpool2/pcp/pcp_proc_info.c +261 -0
  143. data/pgpool2/pcp/pcp_promote_node.c +185 -0
  144. data/pgpool2/pcp/pcp_recovery_node.c +172 -0
  145. data/pgpool2/pcp/pcp_stop_pgpool.c +179 -0
  146. data/pgpool2/pcp/pcp_stream.c +385 -0
  147. data/pgpool2/pcp/pcp_stream.h +52 -0
  148. data/pgpool2/pcp/pcp_systemdb_info.c +194 -0
  149. data/pgpool2/pcp/pcp_watchdog_info.c +211 -0
  150. data/pgpool2/pcp_child.c +1493 -0
  151. data/pgpool2/pg_md5.c +305 -0
  152. data/pgpool2/pgpool.8.in +121 -0
  153. data/pgpool2/pgpool.conf +553 -0
  154. data/pgpool2/pgpool.conf.sample +666 -0
  155. data/pgpool2/pgpool.conf.sample-master-slave +665 -0
  156. data/pgpool2/pgpool.conf.sample-replication +664 -0
  157. data/pgpool2/pgpool.conf.sample-stream +664 -0
  158. data/pgpool2/pgpool.spec +264 -0
  159. data/pgpool2/pgpool_adm/TODO +7 -0
  160. data/pgpool2/pgpool_adm/pgpool_adm--1.0.sql +85 -0
  161. data/pgpool2/pgpool_adm/pgpool_adm.c +558 -0
  162. data/pgpool2/pgpool_adm/pgpool_adm.control +5 -0
  163. data/pgpool2/pgpool_adm/pgpool_adm.h +46 -0
  164. data/pgpool2/pgpool_adm/pgpool_adm.sql.in +85 -0
  165. data/pgpool2/pool.h +655 -0
  166. data/pgpool2/pool_auth.c +1390 -0
  167. data/pgpool2/pool_config.c +5007 -0
  168. data/pgpool2/pool_config.h +284 -0
  169. data/pgpool2/pool_config.l +3281 -0
  170. data/pgpool2/pool_config_md5.c +29 -0
  171. data/pgpool2/pool_connection_pool.c +812 -0
  172. data/pgpool2/pool_error.c +242 -0
  173. data/pgpool2/pool_globals.c +27 -0
  174. data/pgpool2/pool_hba.c +1723 -0
  175. data/pgpool2/pool_hba.conf.sample +67 -0
  176. data/pgpool2/pool_ip.c +567 -0
  177. data/pgpool2/pool_ip.h +65 -0
  178. data/pgpool2/pool_ipc.h +38 -0
  179. data/pgpool2/pool_lobj.c +242 -0
  180. data/pgpool2/pool_lobj.h +32 -0
  181. data/pgpool2/pool_memqcache.c +3818 -0
  182. data/pgpool2/pool_memqcache.h +268 -0
  183. data/pgpool2/pool_params.c +163 -0
  184. data/pgpool2/pool_passwd.c +249 -0
  185. data/pgpool2/pool_passwd.h +41 -0
  186. data/pgpool2/pool_path.c +193 -0
  187. data/pgpool2/pool_path.h +81 -0
  188. data/pgpool2/pool_process_context.c +247 -0
  189. data/pgpool2/pool_process_context.h +62 -0
  190. data/pgpool2/pool_process_query.c +5001 -0
  191. data/pgpool2/pool_process_reporting.c +1671 -0
  192. data/pgpool2/pool_process_reporting.h +44 -0
  193. data/pgpool2/pool_proto2.c +671 -0
  194. data/pgpool2/pool_proto_modules.c +3524 -0
  195. data/pgpool2/pool_proto_modules.h +185 -0
  196. data/pgpool2/pool_query_cache.c +1020 -0
  197. data/pgpool2/pool_query_context.c +1871 -0
  198. data/pgpool2/pool_query_context.h +105 -0
  199. data/pgpool2/pool_relcache.c +284 -0
  200. data/pgpool2/pool_relcache.h +78 -0
  201. data/pgpool2/pool_rewrite_outfuncs.c +9060 -0
  202. data/pgpool2/pool_rewrite_query.c +715 -0
  203. data/pgpool2/pool_rewrite_query.h +192 -0
  204. data/pgpool2/pool_select_walker.c +1150 -0
  205. data/pgpool2/pool_select_walker.h +68 -0
  206. data/pgpool2/pool_sema.c +161 -0
  207. data/pgpool2/pool_session_context.c +952 -0
  208. data/pgpool2/pool_session_context.h +203 -0
  209. data/pgpool2/pool_shmem.c +185 -0
  210. data/pgpool2/pool_signal.c +158 -0
  211. data/pgpool2/pool_signal.h +61 -0
  212. data/pgpool2/pool_ssl.c +339 -0
  213. data/pgpool2/pool_stream.c +962 -0
  214. data/pgpool2/pool_stream.h +61 -0
  215. data/pgpool2/pool_system.c +659 -0
  216. data/pgpool2/pool_timestamp.c +1215 -0
  217. data/pgpool2/pool_timestamp.h +38 -0
  218. data/pgpool2/pool_type.h +171 -0
  219. data/pgpool2/pool_worker_child.c +384 -0
  220. data/pgpool2/ps_status.c +404 -0
  221. data/pgpool2/recovery.c +435 -0
  222. data/pgpool2/redhat/pgpool.conf.sample.patch +52 -0
  223. data/pgpool2/redhat/pgpool.init +201 -0
  224. data/pgpool2/redhat/pgpool.sysconfig +7 -0
  225. data/pgpool2/redhat/rpm_installer/basebackup-replication.sh +53 -0
  226. data/pgpool2/redhat/rpm_installer/basebackup-stream.sh +55 -0
  227. data/pgpool2/redhat/rpm_installer/config_for_script +17 -0
  228. data/pgpool2/redhat/rpm_installer/failover.sh +64 -0
  229. data/pgpool2/redhat/rpm_installer/getsources.sh +141 -0
  230. data/pgpool2/redhat/rpm_installer/install.sh +1363 -0
  231. data/pgpool2/redhat/rpm_installer/pgpool_recovery_pitr +47 -0
  232. data/pgpool2/redhat/rpm_installer/pgpool_remote_start +15 -0
  233. data/pgpool2/redhat/rpm_installer/recovery.conf +4 -0
  234. data/pgpool2/redhat/rpm_installer/uninstall.sh +57 -0
  235. data/pgpool2/sample/dist_def_pgbench.sql +73 -0
  236. data/pgpool2/sample/pgpool.pam +3 -0
  237. data/pgpool2/sample/pgpool_recovery +20 -0
  238. data/pgpool2/sample/pgpool_recovery_pitr +19 -0
  239. data/pgpool2/sample/pgpool_remote_start +13 -0
  240. data/pgpool2/sample/replicate_def_pgbench.sql +18 -0
  241. data/pgpool2/sql/insert_lock.sql +15 -0
  242. data/pgpool2/sql/pgpool-recovery/pgpool-recovery.c +280 -0
  243. data/pgpool2/sql/pgpool-recovery/pgpool-recovery.sql.in +19 -0
  244. data/pgpool2/sql/pgpool-recovery/pgpool_recovery--1.0.sql +24 -0
  245. data/pgpool2/sql/pgpool-recovery/pgpool_recovery.control +5 -0
  246. data/pgpool2/sql/pgpool-recovery/uninstall_pgpool-recovery.sql +3 -0
  247. data/pgpool2/sql/pgpool-regclass/pgpool-regclass.c +206 -0
  248. data/pgpool2/sql/pgpool-regclass/pgpool-regclass.sql.in +4 -0
  249. data/pgpool2/sql/pgpool-regclass/pgpool_regclass--1.0.sql +7 -0
  250. data/pgpool2/sql/pgpool-regclass/pgpool_regclass.control +5 -0
  251. data/pgpool2/sql/pgpool-regclass/uninstall_pgpool-regclass.sql +1 -0
  252. data/pgpool2/sql/system_db.sql +38 -0
  253. data/pgpool2/strlcpy.c +85 -0
  254. data/pgpool2/test/C/test_extended.c +98 -0
  255. data/pgpool2/test/jdbc/.cvsignore +2 -0
  256. data/pgpool2/test/jdbc/AutoCommitTest.java +45 -0
  257. data/pgpool2/test/jdbc/BatchTest.java +55 -0
  258. data/pgpool2/test/jdbc/ColumnTest.java +60 -0
  259. data/pgpool2/test/jdbc/CreateTempTableTest.java +48 -0
  260. data/pgpool2/test/jdbc/InsertTest.java +34 -0
  261. data/pgpool2/test/jdbc/LockTest.java +36 -0
  262. data/pgpool2/test/jdbc/PgpoolTest.java +75 -0
  263. data/pgpool2/test/jdbc/README.euc_jp +73 -0
  264. data/pgpool2/test/jdbc/RunTest.java +83 -0
  265. data/pgpool2/test/jdbc/SelectTest.java +37 -0
  266. data/pgpool2/test/jdbc/UpdateTest.java +32 -0
  267. data/pgpool2/test/jdbc/expected/CreateTempTable +1 -0
  268. data/pgpool2/test/jdbc/expected/autocommit +10 -0
  269. data/pgpool2/test/jdbc/expected/batch +1 -0
  270. data/pgpool2/test/jdbc/expected/column +100 -0
  271. data/pgpool2/test/jdbc/expected/insert +1 -0
  272. data/pgpool2/test/jdbc/expected/lock +100 -0
  273. data/pgpool2/test/jdbc/expected/select +2 -0
  274. data/pgpool2/test/jdbc/expected/update +1 -0
  275. data/pgpool2/test/jdbc/pgpool.properties +7 -0
  276. data/pgpool2/test/jdbc/prepare.sql +54 -0
  277. data/pgpool2/test/jdbc/run.sh +6 -0
  278. data/pgpool2/test/parser/.cvsignore +6 -0
  279. data/pgpool2/test/parser/README +32 -0
  280. data/pgpool2/test/parser/expected/copy.out +17 -0
  281. data/pgpool2/test/parser/expected/create.out +64 -0
  282. data/pgpool2/test/parser/expected/cursor.out +37 -0
  283. data/pgpool2/test/parser/expected/delete.out +10 -0
  284. data/pgpool2/test/parser/expected/drop.out +12 -0
  285. data/pgpool2/test/parser/expected/insert.out +13 -0
  286. data/pgpool2/test/parser/expected/misc.out +28 -0
  287. data/pgpool2/test/parser/expected/prepare.out +4 -0
  288. data/pgpool2/test/parser/expected/privileges.out +31 -0
  289. data/pgpool2/test/parser/expected/scanner.out +30 -0
  290. data/pgpool2/test/parser/expected/select.out +89 -0
  291. data/pgpool2/test/parser/expected/transaction.out +38 -0
  292. data/pgpool2/test/parser/expected/update.out +11 -0
  293. data/pgpool2/test/parser/expected/v84.out +37 -0
  294. data/pgpool2/test/parser/expected/v90.out +25 -0
  295. data/pgpool2/test/parser/expected/var.out +22 -0
  296. data/pgpool2/test/parser/input/alter.sql +2 -0
  297. data/pgpool2/test/parser/input/copy.sql +17 -0
  298. data/pgpool2/test/parser/input/create.sql +64 -0
  299. data/pgpool2/test/parser/input/cursor.sql +37 -0
  300. data/pgpool2/test/parser/input/delete.sql +10 -0
  301. data/pgpool2/test/parser/input/drop.sql +12 -0
  302. data/pgpool2/test/parser/input/insert.sql +13 -0
  303. data/pgpool2/test/parser/input/misc.sql +28 -0
  304. data/pgpool2/test/parser/input/prepare.sql +4 -0
  305. data/pgpool2/test/parser/input/privileges.sql +31 -0
  306. data/pgpool2/test/parser/input/scanner.sql +34 -0
  307. data/pgpool2/test/parser/input/select.sql +89 -0
  308. data/pgpool2/test/parser/input/transaction.sql +38 -0
  309. data/pgpool2/test/parser/input/update.sql +11 -0
  310. data/pgpool2/test/parser/input/v84.sql +37 -0
  311. data/pgpool2/test/parser/input/v90.sql +38 -0
  312. data/pgpool2/test/parser/input/var.sql +22 -0
  313. data/pgpool2/test/parser/main.c +96 -0
  314. data/pgpool2/test/parser/parse_schedule +16 -0
  315. data/pgpool2/test/parser/pool.h +13 -0
  316. data/pgpool2/test/parser/run-test +62 -0
  317. data/pgpool2/test/pdo-test/README.euc_jp +58 -0
  318. data/pgpool2/test/pdo-test/SQLlist/test1.sql +3 -0
  319. data/pgpool2/test/pdo-test/SQLlist/test2.sql +3 -0
  320. data/pgpool2/test/pdo-test/collections.inc +11 -0
  321. data/pgpool2/test/pdo-test/def.inc +7 -0
  322. data/pgpool2/test/pdo-test/log.txt +0 -0
  323. data/pgpool2/test/pdo-test/mod/database.inc +36 -0
  324. data/pgpool2/test/pdo-test/mod/def.inc +0 -0
  325. data/pgpool2/test/pdo-test/mod/errorhandler.inc +27 -0
  326. data/pgpool2/test/pdo-test/pdotest.php +11 -0
  327. data/pgpool2/test/pdo-test/regsql.inc +56 -0
  328. data/pgpool2/test/pgpool_setup +898 -0
  329. data/pgpool2/test/regression/README +39 -0
  330. data/pgpool2/test/regression/clean.sh +21 -0
  331. data/pgpool2/test/regression/libs.sh +16 -0
  332. data/pgpool2/test/regression/regress.sh +166 -0
  333. data/pgpool2/test/regression/tests/001.load_balance/test.sh +128 -0
  334. data/pgpool2/test/regression/tests/002.native_replication/PgTester.java +47 -0
  335. data/pgpool2/test/regression/tests/002.native_replication/create.sql +6 -0
  336. data/pgpool2/test/regression/tests/002.native_replication/test.sh +71 -0
  337. data/pgpool2/test/regression/tests/003.failover/expected.r +6 -0
  338. data/pgpool2/test/regression/tests/003.failover/expected.s +6 -0
  339. data/pgpool2/test/regression/tests/003.failover/test.sh +45 -0
  340. data/pgpool2/test/regression/tests/004.watchdog/master.conf +12 -0
  341. data/pgpool2/test/regression/tests/004.watchdog/standby.conf +19 -0
  342. data/pgpool2/test/regression/tests/004.watchdog/test.sh +52 -0
  343. data/pgpool2/test/regression/tests/050.bug58/test.sh +50 -0
  344. data/pgpool2/test/regression/tests/051.bug60/bug.sql +12 -0
  345. data/pgpool2/test/regression/tests/051.bug60/database-clean.sql +6 -0
  346. data/pgpool2/test/regression/tests/051.bug60/database-setup.sql +28 -0
  347. data/pgpool2/test/regression/tests/051.bug60/test.sh +79 -0
  348. data/pgpool2/test/regression/tests/052.do_query/test.sh +44 -0
  349. data/pgpool2/test/regression/tests/053.insert_lock_hangs/test.sh +81 -0
  350. data/pgpool2/test/regression/tests/054.postgres_fdw/test.sh +67 -0
  351. data/pgpool2/test/regression/tests/055.backend_all_down/test.sh +52 -0
  352. data/pgpool2/test/regression/tests/056.bug63/jdbctest2.java +66 -0
  353. data/pgpool2/test/regression/tests/056.bug63/test.sh +47 -0
  354. data/pgpool2/test/regression/tests/057.bug61/test.sh +40 -0
  355. data/pgpool2/test/regression/tests/058.bug68/jdbctest3.java +45 -0
  356. data/pgpool2/test/regression/tests/058.bug68/test.sh +47 -0
  357. data/pgpool2/test/timestamp/expected/insert.out +16 -0
  358. data/pgpool2/test/timestamp/expected/misc.out +3 -0
  359. data/pgpool2/test/timestamp/expected/update.out +6 -0
  360. data/pgpool2/test/timestamp/input/insert.sql +16 -0
  361. data/pgpool2/test/timestamp/input/misc.sql +3 -0
  362. data/pgpool2/test/timestamp/input/update.sql +6 -0
  363. data/pgpool2/test/timestamp/main.c +129 -0
  364. data/pgpool2/test/timestamp/parse_schedule +3 -0
  365. data/pgpool2/test/timestamp/run-test +69 -0
  366. data/pgpool2/version.h +1 -0
  367. data/pgpool2/watchdog/Makefile.am +17 -0
  368. data/pgpool2/watchdog/Makefile.in +505 -0
  369. data/pgpool2/watchdog/test/stab.c +266 -0
  370. data/pgpool2/watchdog/test/test.c +85 -0
  371. data/pgpool2/watchdog/test/wd_child_t.c +87 -0
  372. data/pgpool2/watchdog/test/wd_lifecheck_t.c +87 -0
  373. data/pgpool2/watchdog/test/wd_packet_t.c +87 -0
  374. data/pgpool2/watchdog/test/wd_ping_t.c +20 -0
  375. data/pgpool2/watchdog/watchdog.c +408 -0
  376. data/pgpool2/watchdog/watchdog.h +209 -0
  377. data/pgpool2/watchdog/wd_child.c +444 -0
  378. data/pgpool2/watchdog/wd_ext.h +123 -0
  379. data/pgpool2/watchdog/wd_heartbeat.c +577 -0
  380. data/pgpool2/watchdog/wd_if.c +216 -0
  381. data/pgpool2/watchdog/wd_init.c +126 -0
  382. data/pgpool2/watchdog/wd_interlock.c +347 -0
  383. data/pgpool2/watchdog/wd_lifecheck.c +512 -0
  384. data/pgpool2/watchdog/wd_list.c +429 -0
  385. data/pgpool2/watchdog/wd_packet.c +1159 -0
  386. data/pgpool2/watchdog/wd_ping.c +330 -0
  387. data/pgpool2/ylwrap +223 -0
  388. data/pgsql/presto_client.py +346 -0
  389. data/pgsql/prestogres.py +156 -0
  390. data/pgsql/setup_functions.sql +21 -0
  391. data/pgsql/setup_language.sql +3 -0
  392. data/prestogres.gemspec +23 -0
  393. metadata +496 -0
@@ -0,0 +1,1390 @@
1
+ /* -*-pgsql-c-*- */
2
+ /*
3
+ * $Header$
4
+ *
5
+ * pgpool: a language independent connection pool server for PostgreSQL
6
+ * written by Tatsuo Ishii
7
+ *
8
+ * Copyright (c) 2003-2013 PgPool Global Development Group
9
+ *
10
+ * Permission to use, copy, modify, and distribute this software and
11
+ * its documentation for any purpose and without fee is hereby
12
+ * granted, provided that the above copyright notice appear in all
13
+ * copies and that both that copyright notice and this permission
14
+ * notice appear in supporting documentation, and that the name of the
15
+ * author not be used in advertising or publicity pertaining to
16
+ * distribution of the software without specific, written prior
17
+ * permission. The author makes no representations about the
18
+ * suitability of this software for any purpose. It is provided "as
19
+ * is" without express or implied warranty.
20
+ *
21
+ * pool_auth.c: authentication stuff
22
+ *
23
+ */
24
+
25
+ #include "pool.h"
26
+ #include "pool_stream.h"
27
+ #include "pool_config.h"
28
+ #include "pool_passwd.h"
29
+
30
+ #ifdef HAVE_SYS_TYPES_H
31
+ #include <sys/types.h>
32
+ #endif
33
+ #ifdef HAVE_NETINET_IN_H
34
+ #include <netinet/in.h>
35
+ #endif
36
+ #ifdef HAVE_PARAM_H
37
+ #include <param.h>
38
+ #endif
39
+ #include <errno.h>
40
+ #include <string.h>
41
+ #include <stdlib.h>
42
+
43
+ #define AUTHFAIL_ERRORCODE "28000"
44
+
45
+ static POOL_STATUS pool_send_backend_key_data(POOL_CONNECTION *frontend, int pid, int key, int protoMajor);
46
+ static int do_clear_text_password(POOL_CONNECTION *backend, POOL_CONNECTION *frontend, int reauth, int protoMajor);
47
+ static void pool_send_auth_fail(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *cp);
48
+ static int do_crypt(POOL_CONNECTION *backend, POOL_CONNECTION *frontend, int reauth, int protoMajor);
49
+ static int do_md5(POOL_CONNECTION *backend, POOL_CONNECTION *frontend, int reauth, int protoMajor);
50
+ //static int send_md5auth_request(POOL_CONNECTION *frontend, int protoMajor, char *salt);
51
+ //static int read_password_packet(POOL_CONNECTION *frontend, int protoMajor, char *password, int *pwdSize);
52
+ static int send_password_packet(POOL_CONNECTION *backend, int protoMajor, char *password);
53
+ static int send_auth_ok(POOL_CONNECTION *frontend, int protoMajor);
54
+
55
+ /*
56
+ * After sending the start up packet to the backend, do the
57
+ * authentication against backend. if success return 0 otherwise non
58
+ * 0.
59
+ */
60
+ int pool_do_auth(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *cp)
61
+ {
62
+ signed char kind;
63
+ int pid;
64
+ int key;
65
+ int protoMajor;
66
+ int length;
67
+ int authkind;
68
+ int i;
69
+ StartupPacket *sp;
70
+
71
+ protoMajor = MAJOR(cp);
72
+
73
+ kind = pool_read_kind(cp);
74
+ if (kind < 0)
75
+ {
76
+ return -1;
77
+ }
78
+
79
+ /* error response? */
80
+ if (kind == 'E')
81
+ {
82
+ /* we assume error response at this stage is likely version
83
+ * protocol mismatch (v3 frontend vs. v2 backend). So we throw
84
+ * a V2 protocol error response in the hope that v3 frontend
85
+ * will negotiate again using v2 protocol.
86
+ */
87
+ pool_log("pool_do_auth: maybe protocol version mismatch (current version %d)", protoMajor);
88
+ ErrorResponse(frontend, cp);
89
+ return -1;
90
+ }
91
+ else if (kind != 'R')
92
+ {
93
+ pool_error("pool_do_auth: expect \"R\" got %c", kind);
94
+ return -1;
95
+ }
96
+
97
+ /*
98
+ * message length (v3 only)
99
+ */
100
+ if (protoMajor == PROTO_MAJOR_V3 && pool_read_message_length(cp) < 0)
101
+ {
102
+ pool_error("Failed to read the authentication packet length. \
103
+ This is likely caused by the inconsistency of auth method among DB nodes. \
104
+ In this case you can check the previous error messages (hint: length field) \
105
+ from pool_read_message_length and recheck the pg_hba.conf settings.");
106
+ return -1;
107
+ }
108
+
109
+ /*
110
+ * read authentication request kind.
111
+ *
112
+ * 0: authentication ok
113
+ * 1: kerberos v4
114
+ * 2: kerberos v5
115
+ * 3: clear text password
116
+ * 4: crypt password
117
+ * 5: md5 password
118
+ * 6: scm credential
119
+ *
120
+ * in replication mode, we only support kind = 0, 3. this is because "salt"
121
+ * cannot be replicated.
122
+ * in non replication mode, we support kind = 0, 3, 4, 5
123
+ */
124
+
125
+ authkind = pool_read_int(cp);
126
+ if (authkind < 0)
127
+ {
128
+ pool_error("pool_do_auth: read auth kind failed");
129
+ return -1;
130
+ }
131
+
132
+ authkind = ntohl(authkind);
133
+
134
+ pool_debug("pool_do_auth: auth kind:%d", authkind);
135
+
136
+ /* trust? */
137
+ if (authkind == 0)
138
+ {
139
+ int msglen;
140
+
141
+ pool_write(frontend, "R", 1);
142
+
143
+ if (protoMajor == PROTO_MAJOR_V3)
144
+ {
145
+ msglen = htonl(8);
146
+ pool_write(frontend, &msglen, sizeof(msglen));
147
+ }
148
+
149
+ msglen = htonl(0);
150
+ if (pool_write_and_flush(frontend, &msglen, sizeof(msglen)) < 0)
151
+ {
152
+ return -1;
153
+ }
154
+ MASTER(cp)->auth_kind = 0;
155
+ }
156
+
157
+ /* clear text password authentication? */
158
+ else if (authkind == 3)
159
+ {
160
+ for (i=0;i<NUM_BACKENDS;i++)
161
+ {
162
+ if (!VALID_BACKEND(i))
163
+ continue;
164
+
165
+ pool_debug("trying clear text password authentication");
166
+
167
+ authkind = do_clear_text_password(CONNECTION(cp, i), frontend, 0, protoMajor);
168
+
169
+ if (authkind < 0)
170
+ {
171
+ pool_debug("do_clear_text_password failed in slot %d", i);
172
+ pool_send_auth_fail(frontend, cp);
173
+ return -1;
174
+ }
175
+ }
176
+ }
177
+
178
+ /* crypt authentication? */
179
+ else if (authkind == 4)
180
+ {
181
+ for (i=0;i<NUM_BACKENDS;i++)
182
+ {
183
+ if (!VALID_BACKEND(i))
184
+ continue;
185
+
186
+ pool_debug("trying crypt authentication");
187
+
188
+ authkind = do_crypt(CONNECTION(cp, i), frontend, 0, protoMajor);
189
+
190
+ if (authkind < 0)
191
+ {
192
+ pool_debug("do_crypt_text_password failed in slot %d", i);
193
+ pool_send_auth_fail(frontend, cp);
194
+ return -1;
195
+ }
196
+ }
197
+ }
198
+
199
+ /* md5 authentication? */
200
+ else if (authkind == 5)
201
+ {
202
+ /* If MD5 auth is not active in pool_hba.conf, it cannot be
203
+ * used with other than raw mode.
204
+ */
205
+ if (frontend->auth_method != uaMD5 && !RAW_MODE && NUM_BACKENDS > 1)
206
+ {
207
+ pool_send_error_message(frontend, protoMajor, AUTHFAIL_ERRORCODE,
208
+ "MD5 authentication is unsupported in replication, master-slave and parallel modes.",
209
+ "",
210
+ "check pg_hba.conf",
211
+ __FILE__, __LINE__);
212
+ return -1;
213
+ }
214
+
215
+ for (i=0;i<NUM_BACKENDS;i++)
216
+ {
217
+ if (!VALID_BACKEND(i))
218
+ continue;
219
+
220
+ pool_debug("trying md5 authentication");
221
+
222
+ authkind = do_md5(CONNECTION(cp, i), frontend, 0, protoMajor);
223
+
224
+ if (authkind < 0)
225
+ {
226
+ pool_debug("do_md5failed in slot %d", i);
227
+ pool_send_auth_fail(frontend, cp);
228
+ return -1;
229
+ }
230
+ }
231
+ }
232
+
233
+ else
234
+ {
235
+ pool_error("pool_do_auth: unsupported auth kind received: %d", authkind);
236
+ return -1;
237
+ }
238
+
239
+ if (authkind != 0)
240
+ {
241
+ pool_error("pool_do_auth: unknown authentication response from backend %d", authkind);
242
+ return -1;
243
+ }
244
+
245
+ /*
246
+ * authentication ok. now read pid and secret key from the
247
+ * backend
248
+ */
249
+ for (;;)
250
+ {
251
+ char *message;
252
+
253
+ kind = pool_read_kind(cp);
254
+ if (kind < 0)
255
+ {
256
+ pool_error("pool_do_auth: failed to read kind before BackendKeyData");
257
+ return -1;
258
+ }
259
+ else if (kind == 'K')
260
+ break;
261
+
262
+ if (protoMajor == PROTO_MAJOR_V3)
263
+ {
264
+ switch (kind)
265
+ {
266
+ case 'S':
267
+ /* process parameter status */
268
+ if (ParameterStatus(frontend, cp) != POOL_CONTINUE)
269
+ return -1;
270
+ pool_flush(frontend);
271
+ break;
272
+
273
+ case 'N':
274
+ if (pool_extract_error_message(true, MASTER(cp), protoMajor, true, &message) == 1)
275
+ {
276
+ pool_log("pool_do_auth: notice message from backend:%s", message);
277
+ }
278
+ /* process notice message */
279
+ if (SimpleForwardToFrontend(kind, frontend, cp))
280
+ return -1;
281
+ pool_flush(frontend);
282
+ break;
283
+
284
+ /* process error message */
285
+ case 'E':
286
+ if (pool_extract_error_message(true, MASTER(cp), protoMajor, true, &message) == 1)
287
+ {
288
+ pool_log("pool_do_auth: error message from backend:%s", message);
289
+ }
290
+ SimpleForwardToFrontend(kind, frontend, cp);
291
+ pool_flush(frontend);
292
+ return -1;
293
+ break;
294
+
295
+ default:
296
+ pool_error("pool_do_auth: unknown response \"%c\" before processing BackendKeyData",
297
+ kind);
298
+ return -1;
299
+ break;
300
+ }
301
+ }
302
+ else
303
+ {
304
+ /* V2 case */
305
+ switch (kind)
306
+ {
307
+ case 'N':
308
+ /* process notice message */
309
+ if (NoticeResponse(frontend, cp) != POOL_CONTINUE)
310
+ return -1;
311
+ break;
312
+
313
+ /* process error message */
314
+ case 'E':
315
+ ErrorResponse(frontend, cp);
316
+ return -1;
317
+ break;
318
+
319
+ default:
320
+ pool_error("pool_do_auth: unknown response \"%c\" before processing V2 BackendKeyData",
321
+ kind);
322
+ return -1;
323
+ break;
324
+ }
325
+ }
326
+ }
327
+
328
+ /*
329
+ * message length (V3 only)
330
+ */
331
+ if (protoMajor == PROTO_MAJOR_V3)
332
+ {
333
+ if (kind != 'K')
334
+ {
335
+ pool_error("pool_do_auth: expect \"K\" got %c", kind);
336
+ return -1;
337
+ }
338
+
339
+ if ((length = pool_read_message_length(cp)) != 12)
340
+ {
341
+ pool_error("pool_do_auth: invalid messages length(%d) for BackendKeyData", length);
342
+ return -1;
343
+ }
344
+ }
345
+
346
+ /*
347
+ * OK, read pid and secret key
348
+ */
349
+ sp = MASTER_CONNECTION(cp)->sp;
350
+ pid = -1;
351
+
352
+ for (i=0;i<NUM_BACKENDS;i++)
353
+ {
354
+ if (VALID_BACKEND(i))
355
+ {
356
+ /* read pid */
357
+ if (pool_read(CONNECTION(cp, i), &pid, sizeof(pid)) < 0)
358
+ {
359
+ pool_error("pool_do_auth: failed to read pid in slot %d", i);
360
+ return -1;
361
+ }
362
+
363
+ pool_debug("pool_do_auth: cp->info[i]:%p pid:%u", &cp->info[i], ntohl(pid));
364
+
365
+ CONNECTION_SLOT(cp, i)->pid = cp->info[i].pid = pid;
366
+
367
+ /* read key */
368
+ if (pool_read(CONNECTION(cp, i), &key, sizeof(key)) < 0)
369
+ {
370
+ pool_error("pool_do_auth: failed to read key in slot %d", i);
371
+ return -1;
372
+ }
373
+ CONNECTION_SLOT(cp, i)->key = cp->info[i].key = key;
374
+
375
+ cp->info[i].major = sp->major;
376
+ cp->info[i].minor = sp->minor;
377
+ strlcpy(cp->info[i].database, sp->database, sizeof(cp->info[i].database));
378
+ strlcpy(cp->info[i].user, sp->user, sizeof(cp->info[i].user));
379
+ cp->info[i].counter = 1;
380
+ }
381
+ }
382
+
383
+ if (pid == -1)
384
+ {
385
+ pool_error("pool_do_auth: all backends are down");
386
+ return -1;
387
+ }
388
+
389
+ return pool_send_backend_key_data(frontend, pid, key, protoMajor);
390
+ }
391
+
392
+ /*
393
+ * do re-authentication for reused connection. if success return 0 otherwise non 0.
394
+ */
395
+ int pool_do_reauth(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *cp)
396
+ {
397
+ int status;
398
+ int protoMajor;
399
+
400
+ protoMajor = MAJOR(cp);
401
+
402
+ switch(MASTER(cp)->auth_kind)
403
+ {
404
+ case 0:
405
+ /* trust */
406
+ status = 0;
407
+ break;
408
+
409
+ case 3:
410
+ /* clear text password */
411
+ status = do_clear_text_password(MASTER(cp), frontend, 1, protoMajor);
412
+ break;
413
+
414
+ case 4:
415
+ /* crypt password */
416
+ status = do_crypt(MASTER(cp), frontend, 1, protoMajor);
417
+ break;
418
+
419
+ case 5:
420
+ /* md5 password */
421
+ status = do_md5(MASTER(cp), frontend, 1, protoMajor);
422
+ break;
423
+
424
+ default:
425
+ pool_error("pool_do_reauth: unknown authentication request code %d",
426
+ MASTER(cp)->auth_kind);
427
+ return -1;
428
+ }
429
+
430
+ if (status == 0)
431
+ {
432
+ int msglen;
433
+
434
+ pool_write(frontend, "R", 1);
435
+
436
+ if (protoMajor == PROTO_MAJOR_V3)
437
+ {
438
+ msglen = htonl(8);
439
+ pool_write(frontend, &msglen, sizeof(msglen));
440
+ }
441
+
442
+ msglen = htonl(0);
443
+ if (pool_write_and_flush(frontend, &msglen, sizeof(msglen)) < 0)
444
+ {
445
+ return -1;
446
+ }
447
+ }
448
+ else
449
+ {
450
+ pool_debug("pool_do_reauth: authentication failed");
451
+ pool_send_auth_fail(frontend, cp);
452
+ return -1;
453
+ }
454
+
455
+ return (pool_send_backend_key_data(frontend, MASTER_CONNECTION(cp)->pid, MASTER_CONNECTION(cp)->key, protoMajor) != POOL_CONTINUE);
456
+ }
457
+
458
+ /*
459
+ * send authentication failure message text to frontend
460
+ */
461
+ static void pool_send_auth_fail(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *cp)
462
+ {
463
+ int messagelen;
464
+ char *errmessage;
465
+ int protoMajor;
466
+
467
+ bool send_error_to_frontend = true;
468
+
469
+ protoMajor = MAJOR(cp);
470
+
471
+ messagelen = strlen(MASTER_CONNECTION(cp)->sp->user) + 100;
472
+ if ((errmessage = (char *)malloc(messagelen+1)) == NULL)
473
+ {
474
+ pool_error("pool_send_auth_fail_failed: malloc failed: %s", strerror(errno));
475
+ child_exit(1);
476
+ }
477
+
478
+ snprintf(errmessage, messagelen, "password authentication failed for user \"%s\"",
479
+ MASTER_CONNECTION(cp)->sp->user);
480
+ if (send_error_to_frontend)
481
+ pool_send_fatal_message(frontend, protoMajor, "XX000", errmessage,
482
+ "", "", __FILE__, __LINE__);
483
+ free(errmessage);
484
+ }
485
+
486
+ /*
487
+ * Send backend key data to frontend. if success return 0 otherwise non 0.
488
+ */
489
+ static POOL_STATUS pool_send_backend_key_data(POOL_CONNECTION *frontend, int pid, int key, int protoMajor)
490
+ {
491
+ char kind;
492
+ int len;
493
+
494
+ /* Send backend key data */
495
+ kind = 'K';
496
+ pool_write(frontend, &kind, 1);
497
+ if (protoMajor == PROTO_MAJOR_V3)
498
+ {
499
+ len = htonl(12);
500
+ pool_write(frontend, &len, sizeof(len));
501
+ }
502
+
503
+ pool_debug("pool_send_auth_ok: send pid %d to frontend", ntohl(pid));
504
+
505
+ pool_write(frontend, &pid, sizeof(pid));
506
+ if (pool_write_and_flush(frontend, &key, sizeof(key)) < 0)
507
+ {
508
+ return -1;
509
+ }
510
+
511
+ return 0;
512
+ }
513
+
514
+ /*
515
+ * perform clear text password authentication
516
+ */
517
+ static int do_clear_text_password(POOL_CONNECTION *backend, POOL_CONNECTION *frontend, int reauth, int protoMajor)
518
+ {
519
+ static int size;
520
+ static char password[MAX_PASSWORD_SIZE];
521
+ char response;
522
+ int kind;
523
+ int len;
524
+
525
+ /* master? */
526
+ if (IS_MASTER_NODE_ID(backend->db_node_id))
527
+ {
528
+ pool_write(frontend, "R", 1); /* authentication */
529
+ if (protoMajor == PROTO_MAJOR_V3)
530
+ {
531
+ len = htonl(8);
532
+ pool_write(frontend, &len, sizeof(len));
533
+ }
534
+ kind = htonl(3); /* clear text password authentication */
535
+ pool_write_and_flush(frontend, &kind, sizeof(kind)); /* indicating clear text password authentication */
536
+
537
+ /* read password packet */
538
+ if (protoMajor == PROTO_MAJOR_V2)
539
+ {
540
+ if (pool_read(frontend, &size, sizeof(size)))
541
+ {
542
+ pool_debug("do_clear_text_password: failed to read password packet size");
543
+ return -1;
544
+ }
545
+ }
546
+ else
547
+ {
548
+ char k;
549
+
550
+ if (pool_read(frontend, &k, sizeof(k)))
551
+ {
552
+ pool_debug("do_clear_text_password: failed to read password packet \"p\"");
553
+ return -1;
554
+ }
555
+ if (k != 'p')
556
+ {
557
+ pool_error("do_clear_text_password: password packet does not start with \"p\"");
558
+ return -1;
559
+ }
560
+ if (pool_read(frontend, &size, sizeof(size)))
561
+ {
562
+ pool_error("do_clear_text_password: failed to read password packet size");
563
+ return -1;
564
+ }
565
+ }
566
+
567
+ if ((ntohl(size) - 4) > sizeof(password))
568
+ {
569
+ pool_error("do_clear_text_password: password is too long (size: %d)", ntohl(size) - 4);
570
+ return -1;
571
+ }
572
+
573
+ if (pool_read(frontend, password, ntohl(size) - 4))
574
+ {
575
+ pool_error("do_clear_text_password: failed to read password (size: %d)", ntohl(size) - 4);
576
+ return -1;
577
+ }
578
+ }
579
+
580
+ /* connection reusing? */
581
+ if (reauth)
582
+ {
583
+ if ((ntohl(size) - 4) != backend->pwd_size)
584
+ {
585
+ pool_debug("do_clear_text_password; password size does not match in re-authentication");
586
+ return -1;
587
+ }
588
+
589
+ if (memcmp(password, backend->password, backend->pwd_size) != 0)
590
+ {
591
+ pool_debug("do_clear_text_password; password does not match in re-authentication");
592
+ return -1;
593
+ }
594
+
595
+ return 0;
596
+ }
597
+
598
+ /* send password packet to backend */
599
+ if (protoMajor == PROTO_MAJOR_V3)
600
+ pool_write(backend, "p", 1);
601
+ pool_write(backend, &size, sizeof(size));
602
+ pool_write_and_flush(backend, password, ntohl(size) -4);
603
+ if (pool_read(backend, &response, sizeof(response)))
604
+ {
605
+ pool_error("do_clear_text_password: failed to read authentication response");
606
+ return -1;
607
+ }
608
+
609
+ if (response != 'R')
610
+ {
611
+ pool_debug("do_clear_text_password: backend does not return R while processing clear text password authentication");
612
+ return -1;
613
+ }
614
+
615
+ if (protoMajor == PROTO_MAJOR_V3)
616
+ {
617
+ if (pool_read(backend, &len, sizeof(len)))
618
+ {
619
+ pool_error("do_clear_text_password: failed to read authentication packet size");
620
+ return -1;
621
+ }
622
+
623
+ if (ntohl(len) != 8)
624
+ {
625
+ pool_error("do_clear_text_password: incorrect authentication packet size (%d)", ntohl(len));
626
+ return -1;
627
+ }
628
+ }
629
+
630
+ /* expect to read "Authentication OK" response. kind should be 0... */
631
+ if (pool_read(backend, &kind, sizeof(kind)))
632
+ {
633
+ pool_debug("do_clear_text_password: failed to read Authentication OK response");
634
+ return -1;
635
+ }
636
+
637
+ /* if authenticated, save info */
638
+ if (!reauth && kind == 0)
639
+ {
640
+ if (IS_MASTER_NODE_ID(backend->db_node_id))
641
+ {
642
+ int msglen;
643
+
644
+ pool_write(frontend, "R", 1);
645
+
646
+ if (protoMajor == PROTO_MAJOR_V3)
647
+ {
648
+ msglen = htonl(8);
649
+ pool_write(frontend, &msglen, sizeof(msglen));
650
+ }
651
+
652
+ msglen = htonl(0);
653
+ if (pool_write_and_flush(frontend, &msglen, sizeof(msglen)) < 0)
654
+ {
655
+ return -1;
656
+ }
657
+ }
658
+
659
+ backend->auth_kind = 3;
660
+ backend->pwd_size = ntohl(size) - 4;
661
+ memcpy(backend->password, password, backend->pwd_size);
662
+ }
663
+ return kind;
664
+ }
665
+
666
+ /*
667
+ * perform crypt authentication
668
+ */
669
+ static int do_crypt(POOL_CONNECTION *backend, POOL_CONNECTION *frontend, int reauth, int protoMajor)
670
+ {
671
+ char salt[2];
672
+ static int size;
673
+ static char password[MAX_PASSWORD_SIZE];
674
+ char response;
675
+ int kind;
676
+ int len;
677
+
678
+ if (!reauth)
679
+ {
680
+ /* read salt */
681
+ if (pool_read(backend, salt, sizeof(salt)))
682
+ {
683
+ pool_error("do_crypt: failed to read salt");
684
+ return -1;
685
+ }
686
+ }
687
+ else
688
+ {
689
+ memcpy(salt, backend->salt, sizeof(salt));
690
+ }
691
+
692
+ /* master? */
693
+ if (IS_MASTER_NODE_ID(backend->db_node_id))
694
+ {
695
+ pool_write(frontend, "R", 1); /* authentication */
696
+ if (protoMajor == PROTO_MAJOR_V3)
697
+ {
698
+ len = htonl(10);
699
+ pool_write(frontend, &len, sizeof(len));
700
+ }
701
+ kind = htonl(4); /* crypt authentication */
702
+ pool_write(frontend, &kind, sizeof(kind)); /* indicating crypt authentication */
703
+ pool_write_and_flush(frontend, salt, sizeof(salt)); /* salt */
704
+
705
+ /* read password packet */
706
+ if (protoMajor == PROTO_MAJOR_V2)
707
+ {
708
+ if (pool_read(frontend, &size, sizeof(size)))
709
+ {
710
+ pool_error("do_crypt: failed to read password packet size");
711
+ return -1;
712
+ }
713
+ }
714
+ else
715
+ {
716
+ char k;
717
+
718
+ if (pool_read(frontend, &k, sizeof(k)))
719
+ {
720
+ pool_debug("do_crypt_password: failed to read password packet \"p\"");
721
+ return -1;
722
+ }
723
+ if (k != 'p')
724
+ {
725
+ pool_error("do_crypt_password: password packet does not start with \"p\"");
726
+ return -1;
727
+ }
728
+ if (pool_read(frontend, &size, sizeof(size)))
729
+ {
730
+ pool_error("do_crypt_password: failed to read password packet size");
731
+ return -1;
732
+ }
733
+ }
734
+
735
+ if ((ntohl(size) - 4) > sizeof(password))
736
+ {
737
+ pool_error("do_crypt: password is too long(size: %d)", ntohl(size) - 4);
738
+ return -1;
739
+ }
740
+
741
+ if (pool_read(frontend, password, ntohl(size) - 4))
742
+ {
743
+ pool_error("do_crypt: failed to read password (size: %d)", ntohl(size) - 4);
744
+ return -1;
745
+ }
746
+ }
747
+
748
+ /* connection reusing? */
749
+ if (reauth)
750
+ {
751
+ pool_debug("size: %d saved_size: %d", (ntohl(size) - 4), backend->pwd_size);
752
+ if ((ntohl(size) - 4) != backend->pwd_size)
753
+ {
754
+ pool_debug("do_crypt: password size does not match in re-authentication");
755
+ return -1;
756
+ }
757
+
758
+ if (memcmp(password, backend->password, backend->pwd_size) != 0)
759
+ {
760
+ pool_debug("do_crypt: password does not match in re-authentication");
761
+ return -1;
762
+ }
763
+
764
+ return 0;
765
+ }
766
+
767
+ /* send password packet to backend */
768
+ if (protoMajor == PROTO_MAJOR_V3)
769
+ pool_write(backend, "p", 1);
770
+ pool_write(backend, &size, sizeof(size));
771
+ pool_write_and_flush(backend, password, ntohl(size) -4);
772
+ if (pool_read(backend, &response, sizeof(response)))
773
+ {
774
+ pool_error("do_crypt: failed to read authentication response");
775
+ return -1;
776
+ }
777
+
778
+ if (response != 'R')
779
+ {
780
+ pool_debug("do_crypt: backend does not return R while processing crypt authentication(%02x) DB node id: %d", response, backend->db_node_id);
781
+ return -1;
782
+ }
783
+
784
+ if (protoMajor == PROTO_MAJOR_V3)
785
+ {
786
+ if (pool_read(backend, &len, sizeof(len)))
787
+ {
788
+ pool_error("do_crypt: failed to read authentication packet size");
789
+ return -1;
790
+ }
791
+
792
+ if (ntohl(len) != 8)
793
+ {
794
+ pool_error("do_crypt: incorrect authentication packet size (%d)", ntohl(len));
795
+ return -1;
796
+ }
797
+ }
798
+
799
+ /* expect to read "Authentication OK" response. kind should be 0... */
800
+ if (pool_read(backend, &kind, sizeof(kind)))
801
+ {
802
+ pool_debug("do_crypt: failed to read Authentication OK response");
803
+ return -1;
804
+ }
805
+
806
+ /* if authenticated, save info */
807
+ if (!reauth && kind == 0)
808
+ {
809
+ int msglen;
810
+
811
+ pool_write(frontend, "R", 1);
812
+
813
+ if (protoMajor == PROTO_MAJOR_V3)
814
+ {
815
+ msglen = htonl(8);
816
+ pool_write(frontend, &msglen, sizeof(msglen));
817
+ }
818
+
819
+ msglen = htonl(0);
820
+ if (pool_write_and_flush(frontend, &msglen, sizeof(msglen)) < 0)
821
+ {
822
+ return -1;
823
+ }
824
+
825
+ backend->auth_kind = 4;
826
+ backend->pwd_size = ntohl(size) - 4;
827
+ memcpy(backend->password, password, backend->pwd_size);
828
+ memcpy(backend->salt, salt, sizeof(salt));
829
+ }
830
+ return kind;
831
+ }
832
+
833
+ /*
834
+ * perform MD5 authentication
835
+ */
836
+ static int do_md5(POOL_CONNECTION *backend, POOL_CONNECTION *frontend, int reauth, int protoMajor)
837
+ {
838
+ char salt[4];
839
+ static int size;
840
+ static char password[MAX_PASSWORD_SIZE];
841
+ int kind;
842
+ char encbuf[POOL_PASSWD_LEN+1];
843
+ char *pool_passwd = NULL;
844
+
845
+ if (NUM_BACKENDS > 1)
846
+ {
847
+ /* Read password entry from pool_passwd */
848
+ pool_passwd = pool_get_passwd(frontend->username);
849
+ if (!pool_passwd)
850
+ {
851
+ pool_debug("do_md5: %s does not exist in pool_passwd", frontend->username);
852
+ return -1;
853
+ }
854
+
855
+ /* master? */
856
+ if (IS_MASTER_NODE_ID(backend->db_node_id))
857
+ {
858
+ /* Send md5 auth request to frontend with my own salt */
859
+ pool_random_salt(salt);
860
+ if (send_md5auth_request(frontend, protoMajor, salt))
861
+ {
862
+ pool_error("do_md5: send_md5auth_request failed");
863
+ return -1;
864
+ }
865
+
866
+ /* Read password packet */
867
+ if (read_password_packet(frontend, protoMajor, password, &size))
868
+ {
869
+ pool_debug("do_md5: read_password_packet failed");
870
+ return -1;
871
+ }
872
+
873
+ /* Check the password using my salt + pool_passwd */
874
+ pg_md5_encrypt(pool_passwd+strlen("md5"), salt, sizeof(salt), encbuf);
875
+ if (strcmp(password, encbuf))
876
+ {
877
+ /* Password does not match */
878
+ pool_debug("password does not match: frontend:%s pgpool:%s", password, encbuf);
879
+ return -1;
880
+ }
881
+ }
882
+ kind = 0;
883
+
884
+ if (!reauth)
885
+ {
886
+ /*
887
+ * If ok, authenticate against backends using pool_passwd
888
+ */
889
+ /* Read salt */
890
+ if (pool_read(backend, salt, sizeof(salt)))
891
+ {
892
+ pool_error("do_md5: failed to read salt");
893
+ return -1;
894
+ }
895
+ pool_debug("DB node id: %d salt: %hhx%hhx%hhx%hhx", backend->db_node_id,
896
+ salt[0], salt[1], salt[2], salt[3]);
897
+
898
+ /* Encrypt password in pool_passwd using the salt */
899
+ pg_md5_encrypt(pool_passwd+strlen("md5"), salt, sizeof(salt), encbuf);
900
+
901
+ /* Send password packet to backend and receive auth response */
902
+ kind = send_password_packet(backend, protoMajor, encbuf);
903
+ if (kind < 0)
904
+ {
905
+ return -1;
906
+ }
907
+ }
908
+
909
+ if (!reauth && kind == 0)
910
+ {
911
+ if (IS_MASTER_NODE_ID(backend->db_node_id))
912
+ {
913
+ /* Send auth ok to frontend */
914
+ if (send_auth_ok(frontend, protoMajor) < 0)
915
+ {
916
+ pool_error("do_md5: send_auth_ok failed");
917
+ return -1;
918
+ }
919
+ }
920
+
921
+ /* Save the auth info */
922
+ backend->auth_kind = 5;
923
+ }
924
+ return kind;
925
+ }
926
+
927
+ /*
928
+ * Followings are NUM_BACKEND == 1 case.
929
+ */
930
+ if (!reauth)
931
+ {
932
+ /* read salt */
933
+ if (pool_read(backend, salt, sizeof(salt)))
934
+ {
935
+ pool_error("do_md5: failed to read salt");
936
+ return -1;
937
+ }
938
+ pool_debug("DB node id: %d salt: %hhx%hhx%hhx%hhx", backend->db_node_id,
939
+ salt[0], salt[1], salt[2], salt[3]);
940
+ }
941
+ else
942
+ {
943
+ memcpy(salt, backend->salt, sizeof(salt));
944
+ }
945
+
946
+ /* master? */
947
+ if (IS_MASTER_NODE_ID(backend->db_node_id))
948
+ {
949
+ /* Send md5 auth request to frontend */
950
+ if (send_md5auth_request(frontend, protoMajor, salt))
951
+ {
952
+ pool_error("do_md5: send_md5auth_request failed");
953
+ return -1;
954
+ }
955
+
956
+ /* Read password packet */
957
+ if (read_password_packet(frontend, protoMajor, password, &size))
958
+ {
959
+ pool_debug("do_md5: read_password_packet failed");
960
+ return -1;
961
+ }
962
+ }
963
+
964
+ /* connection reusing? */
965
+ if (reauth)
966
+ {
967
+ if (size != backend->pwd_size)
968
+ {
969
+ pool_debug("do_md5; password size does not match in re-authentication");
970
+ return -1;
971
+ }
972
+
973
+ if (memcmp(password, backend->password, backend->pwd_size) != 0)
974
+ {
975
+ pool_debug("do_md5; password does not match in re-authentication");
976
+ return -1;
977
+ }
978
+
979
+ return 0;
980
+ }
981
+
982
+ /* Send password packet to backend and receive auth response */
983
+ kind = send_password_packet(backend, protoMajor, password);
984
+ if (kind < 0)
985
+ {
986
+ return -1;
987
+ }
988
+
989
+ /* If authenticated, reply back to frontend and save info */
990
+ if (!reauth && kind == 0)
991
+ {
992
+ if (send_auth_ok(frontend, protoMajor) < 0)
993
+ {
994
+ pool_error("do_md5: send_auth_ok failed");
995
+ return -1;
996
+ }
997
+
998
+ backend->auth_kind = 5;
999
+ backend->pwd_size = size;
1000
+ memcpy(backend->password, password, backend->pwd_size);
1001
+ memcpy(backend->salt, salt, sizeof(salt));
1002
+ }
1003
+ return kind;
1004
+ }
1005
+
1006
+ /*
1007
+ * Send md5 authentication request packet to frontend
1008
+ */
1009
+ int send_md5auth_request(POOL_CONNECTION *frontend, int protoMajor, char *salt)
1010
+ {
1011
+ int len;
1012
+ int kind;
1013
+
1014
+ pool_write(frontend, "R", 1); /* authentication */
1015
+ if (protoMajor == PROTO_MAJOR_V3)
1016
+ {
1017
+ len = htonl(12);
1018
+ pool_write(frontend, &len, sizeof(len));
1019
+ }
1020
+ kind = htonl(5);
1021
+ pool_write(frontend, &kind, sizeof(kind)); /* indicating MD5 */
1022
+ pool_write_and_flush(frontend, salt, 4); /* salt */
1023
+
1024
+ return 0;
1025
+ }
1026
+
1027
+ /*
1028
+ * Read password packet from frontend
1029
+ */
1030
+ int read_password_packet(POOL_CONNECTION *frontend, int protoMajor, char *password, int *pwdSize)
1031
+ {
1032
+ int size;
1033
+
1034
+ /* Read password packet */
1035
+ if (protoMajor == PROTO_MAJOR_V2)
1036
+ {
1037
+ if (pool_read(frontend, &size, sizeof(size)))
1038
+ {
1039
+ pool_error("read_password_packet: failed to read password packet size");
1040
+ return -1;
1041
+ }
1042
+ }
1043
+ else
1044
+ {
1045
+ char k;
1046
+
1047
+ if (pool_read(frontend, &k, sizeof(k)))
1048
+ {
1049
+ pool_debug("read_password_packet: failed to read password packet \"p\"");
1050
+ return -1;
1051
+ }
1052
+ if (k != 'p')
1053
+ {
1054
+ pool_error("read_password_packet: password packet does not start with \"p\"");
1055
+ return -1;
1056
+ }
1057
+ if (pool_read(frontend, &size, sizeof(size)))
1058
+ {
1059
+ pool_error("read_password_packet: failed to read password packet size");
1060
+ return -1;
1061
+ }
1062
+ }
1063
+
1064
+ *pwdSize = ntohl(size) - 4;
1065
+ if (*pwdSize > MAX_PASSWORD_SIZE)
1066
+ {
1067
+ pool_error("read_password_packet: too long password string (size: %d)", *pwdSize);
1068
+ /*
1069
+ * We do not read to throw away packet here. Since it is possible that
1070
+ * it's a denial of service attack.
1071
+ */
1072
+ return -1;
1073
+ }
1074
+ else if (*pwdSize <= 0)
1075
+ {
1076
+ pool_error("read_password_packet: invalid password string size (size: %d)", *pwdSize);
1077
+ return -1;
1078
+ }
1079
+
1080
+ if (pool_read(frontend, password, *pwdSize))
1081
+ {
1082
+ pool_error("read_password_packet: failed to read password (size: %d)", *pwdSize);
1083
+ return -1;
1084
+ }
1085
+
1086
+ password[*pwdSize] = '\0';
1087
+
1088
+ return 0;
1089
+ }
1090
+
1091
+ /*
1092
+ * Send password packet to backend and receive authentication response
1093
+ * packet. Return value is the last field of authentication
1094
+ * response. If it's 0, authentication was successful.
1095
+ * "password" must be null-terminated.
1096
+ */
1097
+ static int send_password_packet(POOL_CONNECTION *backend, int protoMajor, char *password)
1098
+ {
1099
+ int size;
1100
+ int len;
1101
+ int kind;
1102
+ char response;
1103
+
1104
+ /* Send password packet to backend */
1105
+ if (protoMajor == PROTO_MAJOR_V3)
1106
+ pool_write(backend, "p", 1);
1107
+ size = htonl(sizeof(size) + strlen(password)+1);
1108
+ pool_write(backend, &size, sizeof(size));
1109
+ pool_write_and_flush(backend, password, strlen(password)+1);
1110
+
1111
+ if (pool_read(backend, &response, sizeof(response)))
1112
+ {
1113
+ pool_error("send_password_packet: failed to read authentication response");
1114
+ return -1;
1115
+ }
1116
+
1117
+ if (response != 'R')
1118
+ {
1119
+ pool_debug("send_password_packet: backend does not return R");
1120
+ return -1;
1121
+ }
1122
+
1123
+ if (protoMajor == PROTO_MAJOR_V3)
1124
+ {
1125
+ if (pool_read(backend, &len, sizeof(len)))
1126
+ {
1127
+ pool_error("send_password_packet: failed to read authentication packet size");
1128
+ return -1;
1129
+ }
1130
+
1131
+ if (ntohl(len) != 8)
1132
+ {
1133
+ pool_error("send_password_packet: incorrect authentication packet size (%d)", ntohl(len));
1134
+ return -1;
1135
+ }
1136
+ }
1137
+
1138
+ /* Expect to read "Authentication OK" response. kind should be 0... */
1139
+ if (pool_read(backend, &kind, sizeof(kind)))
1140
+ {
1141
+ pool_debug("send_password_packet: failed to read Authentication OK response");
1142
+ return -1;
1143
+ }
1144
+
1145
+ return kind;
1146
+ }
1147
+
1148
+ /*
1149
+ * Send auth ok to frontend
1150
+ */
1151
+ static int send_auth_ok(POOL_CONNECTION *frontend, int protoMajor)
1152
+ {
1153
+ int msglen;
1154
+
1155
+ pool_write(frontend, "R", 1);
1156
+
1157
+ if (protoMajor == PROTO_MAJOR_V3)
1158
+ {
1159
+ msglen = htonl(8);
1160
+ pool_write(frontend, &msglen, sizeof(msglen));
1161
+ }
1162
+
1163
+ msglen = htonl(0);
1164
+ if (pool_write_and_flush(frontend, &msglen, sizeof(msglen)) < 0)
1165
+ {
1166
+ return -1;
1167
+ }
1168
+ return 0;
1169
+ }
1170
+
1171
+ /*
1172
+ * read message length (V3 only)
1173
+ */
1174
+ int pool_read_message_length(POOL_CONNECTION_POOL *cp)
1175
+ {
1176
+ int status;
1177
+ int length, length0;
1178
+ int i;
1179
+
1180
+ /* read message from master node */
1181
+ status = pool_read(CONNECTION(cp, MASTER_NODE_ID), &length0, sizeof(length0));
1182
+ if (status < 0)
1183
+ {
1184
+ pool_error("pool_read_message_length: error while reading message length in slot %d", MASTER_NODE_ID);
1185
+ return -1;
1186
+ }
1187
+ length0 = ntohl(length0);
1188
+ pool_debug("pool_read_message_length: slot: %d length: %d", MASTER_NODE_ID, length0);
1189
+
1190
+ for (i=0;i<NUM_BACKENDS;i++)
1191
+ {
1192
+ if (!VALID_BACKEND(i) || IS_MASTER_NODE_ID(i))
1193
+ {
1194
+ continue;
1195
+ }
1196
+
1197
+ status = pool_read(CONNECTION(cp, i), &length, sizeof(length));
1198
+ if (status < 0)
1199
+ {
1200
+ pool_error("pool_read_message_length: error while reading message length in slot %d", i);
1201
+ return -1;
1202
+ }
1203
+
1204
+ length = ntohl(length);
1205
+ pool_debug("pool_read_message_length: slot: %d length: %d", i, length);
1206
+
1207
+ if (length != length0)
1208
+ {
1209
+ pool_error("pool_read_message_length: message length (%d) in slot %d does not match with slot 0(%d)", length, i, length0);
1210
+ return -1;
1211
+ }
1212
+ }
1213
+
1214
+ if (length0 < 0)
1215
+ {
1216
+ pool_error("pool_read_message_length: invalid message length (%d)", length);
1217
+ return -1;
1218
+ }
1219
+
1220
+ return length0;
1221
+ }
1222
+
1223
+ /*
1224
+ * read message length2 (V3 only)
1225
+ * unlike pool_read_message_length, this returns an array of message length.
1226
+ * The array is in the static storage, thus it will be destroyed by subsequent calls.
1227
+ */
1228
+ int *pool_read_message_length2(POOL_CONNECTION_POOL *cp)
1229
+ {
1230
+ int status;
1231
+ int length, length0;
1232
+ int i;
1233
+ static int length_array[MAX_CONNECTION_SLOTS];
1234
+
1235
+ /* read message from master node */
1236
+ status = pool_read(CONNECTION(cp, MASTER_NODE_ID), &length0, sizeof(length0));
1237
+ if (status < 0)
1238
+ {
1239
+ pool_error("pool_read_message_length2: error while reading message length in slot %d", MASTER_NODE_ID);
1240
+ return NULL;
1241
+ }
1242
+
1243
+ length0 = ntohl(length0);
1244
+ length_array[MASTER_NODE_ID] = length0;
1245
+ pool_debug("pool_read_message_length2: master slot: %d length: %d", MASTER_NODE_ID, length0);
1246
+ for (i=0;i<NUM_BACKENDS;i++)
1247
+ {
1248
+ if (VALID_BACKEND(i) && !IS_MASTER_NODE_ID(i))
1249
+ {
1250
+ status = pool_read(CONNECTION(cp, i), &length, sizeof(length));
1251
+ if (status < 0)
1252
+ {
1253
+ pool_error("pool_read_message_length2: error while reading message length in slot %d", i);
1254
+ return NULL;
1255
+ }
1256
+
1257
+ length = ntohl(length);
1258
+ pool_debug("pool_read_message_length2: master slot: %d length: %d", i, length);
1259
+
1260
+ if (length != length0)
1261
+ {
1262
+ pool_log("pool_read_message_length2: message length (%d) in slot %d does not match with slot 0(%d)", length, i, length0);
1263
+ }
1264
+
1265
+ if (length < 0)
1266
+ {
1267
+ pool_error("pool_read_message_length2: invalid message length (%d)", length);
1268
+ return NULL;
1269
+ }
1270
+
1271
+ length_array[i] = length;
1272
+ }
1273
+
1274
+ }
1275
+ return &length_array[0];
1276
+ }
1277
+
1278
+ signed char pool_read_kind(POOL_CONNECTION_POOL *cp)
1279
+ {
1280
+ int status;
1281
+ char kind0, kind;
1282
+ int i;
1283
+
1284
+ kind = -1;
1285
+ kind0 = 0;
1286
+
1287
+ for (i=0;i<NUM_BACKENDS;i++)
1288
+ {
1289
+ if (!VALID_BACKEND(i))
1290
+ {
1291
+ continue;
1292
+ }
1293
+
1294
+ status = pool_read(CONNECTION(cp, i), &kind, sizeof(kind));
1295
+ if (status < 0)
1296
+ {
1297
+ pool_error("pool_read_kind: error while reading message kind");
1298
+ return -1;
1299
+ }
1300
+
1301
+ if (IS_MASTER_NODE_ID(i))
1302
+ {
1303
+ kind0 = kind;
1304
+ }
1305
+ else
1306
+ {
1307
+ if (kind != kind0)
1308
+ {
1309
+ char *message;
1310
+
1311
+ pool_error("pool_read_kind: kind does not match between master(%x) slot[%d] (%x)",
1312
+ kind0, i, kind);
1313
+ if (kind0 == 'E')
1314
+ {
1315
+ if (pool_extract_error_message(false, MASTER(cp), MAJOR(cp), true, &message) == 1)
1316
+ {
1317
+ pool_log("pool_read_kind: error message from master backend:%s", message);
1318
+ }
1319
+ }
1320
+ else if (kind == 'E')
1321
+ {
1322
+ if (pool_extract_error_message(false, CONNECTION(cp, i), MAJOR(cp), true, &message) == 1)
1323
+ {
1324
+ pool_log("pool_read_kind: error message from %d th backend:%s", i, message);
1325
+ }
1326
+ }
1327
+ return -1;
1328
+ }
1329
+ }
1330
+ }
1331
+
1332
+ return kind;
1333
+ }
1334
+
1335
+ int pool_read_int(POOL_CONNECTION_POOL *cp)
1336
+ {
1337
+ int status;
1338
+ int data0, data;
1339
+ int i;
1340
+
1341
+ data = -1;
1342
+ data0 = 0;
1343
+
1344
+ for (i=0;i<NUM_BACKENDS;i++)
1345
+ {
1346
+ if (!VALID_BACKEND(i))
1347
+ {
1348
+ continue;
1349
+ }
1350
+
1351
+ status = pool_read(CONNECTION(cp, i), &data, sizeof(data));
1352
+ if (status < 0)
1353
+ {
1354
+ pool_error("pool_read_int: error while reading message data");
1355
+ return -1;
1356
+ }
1357
+
1358
+ if (IS_MASTER_NODE_ID(i))
1359
+ {
1360
+ data0 = data;
1361
+ }
1362
+ else
1363
+ {
1364
+ if (data != data0)
1365
+ {
1366
+ pool_error("pool_read_int: data does not match between between master(%x) slot[%d] (%x)",
1367
+ data0, i, data);
1368
+ return -1;
1369
+ }
1370
+ }
1371
+ }
1372
+
1373
+ return data;
1374
+ }
1375
+
1376
+ /*
1377
+ * pool_random_salt
1378
+ */
1379
+ void pool_random_salt(char *md5Salt)
1380
+ {
1381
+ long rand = random();
1382
+
1383
+ md5Salt[0] = (rand % 255) + 1;
1384
+ rand = random();
1385
+ md5Salt[1] = (rand % 255) + 1;
1386
+ rand = random();
1387
+ md5Salt[2] = (rand % 255) + 1;
1388
+ rand = random();
1389
+ md5Salt[3] = (rand % 255) + 1;
1390
+ }