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,242 @@
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-2012 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_error.c: error and debug messages
22
+ *
23
+ */
24
+
25
+ #include <stdio.h>
26
+ #include <stdarg.h>
27
+ #include <sys/types.h>
28
+ #include <unistd.h>
29
+ #include <stdlib.h>
30
+
31
+ #include "pool.h"
32
+ #include "pool_config.h"
33
+
34
+ #define MAXSTRFTIME 128
35
+
36
+ extern int debug;
37
+
38
+ static char *nowsec(void);
39
+
40
+ void pool_error(const char *fmt,...)
41
+ {
42
+ va_list ap;
43
+ #ifdef HAVE_ASPRINTF
44
+ char *fmt2;
45
+ int len;
46
+ #endif
47
+
48
+ #ifdef HAVE_SIGPROCMASK
49
+ sigset_t oldmask;
50
+ #else
51
+ int oldmask;
52
+ #endif
53
+ POOL_SETMASK2(&BlockSig, &oldmask);
54
+
55
+ /* Write error message to syslog */
56
+ if (pool_config->logsyslog == 1) {
57
+ va_start(ap, fmt);
58
+ vsyslog(pool_config->syslog_facility | LOG_ERR, fmt, ap);
59
+ va_end(ap);
60
+ POOL_SETMASK(&oldmask);
61
+ return;
62
+ }
63
+
64
+ if (pool_config->print_timestamp)
65
+ #ifdef HAVE_ASPRINTF
66
+ len = asprintf(&fmt2, "%s ERROR: pid %d: %s\n", nowsec(), (int)getpid(), fmt);
67
+ else
68
+ len = asprintf(&fmt2, "ERROR: pid %d: %s\n", (int)getpid(), fmt);
69
+
70
+ if (len >= 0 && fmt2)
71
+ {
72
+ va_start(ap, fmt);
73
+ vfprintf(stderr, fmt2, ap);
74
+ va_end(ap);
75
+ fflush(stderr);
76
+ free(fmt2);
77
+ }
78
+ #else
79
+ fprintf(stderr, "%s ERROR: pid %d: ", nowsec(), (int)getpid());
80
+ else
81
+ fprintf(stderr, "ERROR: pid %d: ", (int)getpid());
82
+
83
+ va_start(ap, fmt);
84
+ vfprintf(stderr, fmt, ap);
85
+ va_end(ap);
86
+ fprintf(stderr, "\n");
87
+ #endif
88
+
89
+ POOL_SETMASK(&oldmask);
90
+ }
91
+
92
+ void pool_debug(const char *fmt,...)
93
+ {
94
+ va_list ap;
95
+ #ifdef HAVE_ASPRINTF
96
+ char *fmt2;
97
+ int len;
98
+ #endif
99
+
100
+ #ifdef HAVE_SIGPROCMASK
101
+ sigset_t oldmask;
102
+ #else
103
+ int oldmask;
104
+ #endif
105
+
106
+ if (run_as_pcp_child)
107
+ {
108
+ if (!debug)
109
+ return;
110
+ }
111
+ else
112
+ {
113
+ if (pool_config->debug_level <= 0)
114
+ return;
115
+ }
116
+
117
+ POOL_SETMASK2(&BlockSig, &oldmask);
118
+
119
+ /* Write debug message to syslog */
120
+ if (pool_config->logsyslog == 1) {
121
+ va_start(ap, fmt);
122
+ vsyslog(pool_config->syslog_facility | LOG_DEBUG, fmt, ap);
123
+ va_end(ap);
124
+ POOL_SETMASK(&oldmask);
125
+ return;
126
+ }
127
+
128
+ if (pool_config->print_timestamp)
129
+ #ifdef HAVE_ASPRINTF
130
+ len = asprintf(&fmt2, "%s DEBUG: pid %d: %s\n", nowsec(), (int)getpid(), fmt);
131
+ else
132
+ len = asprintf(&fmt2, "DEBUG: pid %d: %s\n", (int)getpid(), fmt);
133
+
134
+ if (len >= 0 && fmt2)
135
+ {
136
+ va_start(ap, fmt);
137
+ vfprintf(stderr, fmt2, ap);
138
+ va_end(ap);
139
+ fflush(stderr);
140
+ free(fmt2);
141
+ }
142
+ #else
143
+ fprintf(stderr, "%s DEBUG: pid %d: ", nowsec(), (int)getpid());
144
+ else
145
+ fprintf(stderr, "DEBUG: pid %d: ", (int)getpid());
146
+
147
+ va_start(ap, fmt);
148
+ vfprintf(stderr, fmt, ap);
149
+ va_end(ap);
150
+ fprintf(stderr, "\n");
151
+ #endif
152
+
153
+ POOL_SETMASK(&oldmask);
154
+ }
155
+
156
+ void pool_log(const char *fmt,...)
157
+ {
158
+ va_list ap;
159
+ #ifdef HAVE_ASPRINTF
160
+ char *fmt2;
161
+ int len;
162
+ #endif
163
+
164
+ #ifdef HAVE_SIGPROCMASK
165
+ sigset_t oldmask;
166
+ #else
167
+ int oldmask;
168
+ #endif
169
+
170
+ POOL_SETMASK2(&BlockSig, &oldmask);
171
+
172
+ /* Write log message to syslog */
173
+ if (pool_config->logsyslog == 1) {
174
+ va_start(ap, fmt);
175
+ vsyslog(pool_config->syslog_facility | LOG_NOTICE, fmt, ap);
176
+ va_end(ap);
177
+ POOL_SETMASK(&oldmask);
178
+ return;
179
+ }
180
+
181
+ if (pool_config->print_timestamp)
182
+ #ifdef HAVE_ASPRINTF
183
+ len = asprintf(&fmt2, "%s LOG: pid %d: %s\n", nowsec(), (int)getpid(), fmt);
184
+ else
185
+ len = asprintf(&fmt2, "LOG: pid %d: %s\n", (int)getpid(), fmt);
186
+
187
+ if (len >= 0 && fmt2)
188
+ {
189
+ va_start(ap, fmt);
190
+ vfprintf(stderr, fmt2, ap);
191
+ va_end(ap);
192
+ fflush(stderr);
193
+ free(fmt2);
194
+ }
195
+ #else
196
+ fprintf(stderr, "%s LOG: pid %d: ", nowsec(), (int)getpid());
197
+ else
198
+ fprintf(stderr, "LOG: pid %d: ", (int)getpid());
199
+
200
+ va_start(ap, fmt);
201
+ vfprintf(stderr, fmt, ap);
202
+ va_end(ap);
203
+ fprintf(stderr, "\n");
204
+ #endif
205
+
206
+ POOL_SETMASK(&oldmask);
207
+ }
208
+
209
+ static char *nowsec(void)
210
+ {
211
+ static char strbuf[MAXSTRFTIME];
212
+ time_t now = time(NULL);
213
+
214
+ strftime(strbuf, MAXSTRFTIME, "%Y-%m-%d %H:%M:%S", localtime(&now));
215
+ return strbuf;
216
+ }
217
+
218
+ #ifndef HAVE_VSYSLOG
219
+ void vsyslog (int priority, const char *format, va_list ap)
220
+ {
221
+ #define MAXSYSLOGMSGLEN 1024
222
+
223
+ char *msg = NULL;
224
+
225
+ #ifdef HAVE_VASPRINTF
226
+ vasprintf(&msg, format, ap);
227
+ if (!msg)
228
+ return;
229
+ #else
230
+ msg = malloc(MAXSYSLOGMSGLEN);
231
+ if (!msg)
232
+ return;
233
+
234
+ va_start(ap, format);
235
+ vsnprintf(msg, MAXSYSLOGMSGLEN, format, ap);
236
+ va_end(ap);
237
+ #endif
238
+
239
+ syslog(priority, "%s", msg);
240
+ free(msg);
241
+ }
242
+ #endif /* HAVE_VSYSLOG */
@@ -0,0 +1,27 @@
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-2010 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
+ * Global variables. Should be eventually removed.
22
+ */
23
+ #include "pool.h"
24
+
25
+ int debug = 0; /* non 0 if debug option is given (-d). pcp only */
26
+ pid_t mypid; /* pgpool parent process id */
27
+ bool run_as_pcp_child;
@@ -0,0 +1,1723 @@
1
+ /* -*-pgsql-c-*- */
2
+ /*
3
+ *
4
+ * $Header$
5
+ *
6
+ * pgpool: a language independent connection pool server for PostgreSQL
7
+ * written by Tatsuo Ishii
8
+ *
9
+ * Portions Copyright (c) 2003-2012 PgPool Global Development Group
10
+ * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
11
+ * Portions Copyright (c) 1994, Regents of the University of California *
12
+ * Permission to use, copy, modify, and distribute this software and
13
+ * its documentation for any purpose and without fee is hereby
14
+ * granted, provided that the above copyright notice appear in all
15
+ * copies and that both that copyright notice and this permission
16
+ * notice appear in supporting documentation, and that the name of the
17
+ * author not be used in advertising or publicity pertaining to
18
+ * distribution of the software without specific, written prior
19
+ * permission. The author makes no representations about the
20
+ * suitability of this software for any purpose. It is provided "as
21
+ * is" without express or implied warranty.
22
+ *
23
+ * pool_hba.c.: Routines to handle host based authentication.
24
+ *
25
+ */
26
+
27
+ #include <stdio.h>
28
+ #include <stdlib.h>
29
+ #include <string.h>
30
+ #include <errno.h>
31
+ #include <netdb.h>
32
+
33
+ #include <unistd.h>
34
+ #include <netinet/in.h>
35
+ #include <arpa/inet.h>
36
+
37
+ #include "pool.h"
38
+ #include "pool_path.h"
39
+ #include "pool_ip.h"
40
+ #include "pool_stream.h"
41
+ #include "pool_config.h"
42
+ #include "parser/pool_memory.h"
43
+ #include "parser/pg_list.h"
44
+ #include "pool_passwd.h"
45
+
46
+ #define MULTI_VALUE_SEP "\001" /* delimiter for multi-valued column strings */
47
+ #define MAX_TOKEN 256
48
+
49
+ static List *hba_lines = NIL;
50
+ static List *hba_line_nums = NIL;
51
+ static char *hbaFileName;
52
+
53
+ static POOL_MEMORY_POOL *hba_memory_context = NULL;
54
+
55
+ static void sendAuthRequest(POOL_CONNECTION *frontend, AuthRequest areq);
56
+ static void auth_failed(POOL_CONNECTION *frontend);
57
+ static void close_all_backend_connections(void);
58
+ static bool hba_getauthmethod(POOL_CONNECTION *frontend);
59
+ static bool check_hba(POOL_CONNECTION *frontend);
60
+ static void parse_hba(List *line, int line_num, POOL_CONNECTION *frontend, bool *found_p, bool *error_p);
61
+ static void parse_hba_auth(ListCell **line_item, UserAuth *userauth_p, char **auth_arg_p, bool *error_p);
62
+ static bool check_user(char *user, char *param_str);
63
+ static bool check_db(char *dbname, char *user, char *param_str);
64
+ static void free_lines(List **lines, List **line_nums);
65
+ static void tokenize_file(const char *filename, FILE *file, List **lines, List **line_nums);
66
+ static char *tokenize_inc_file(const char *outer_filename, const char *inc_filename);
67
+ static bool pg_isblank(const char c);
68
+ static void next_token(FILE *fp, char *buf, int bufsz);
69
+ static char * next_token_expand(const char *filename, FILE *file);
70
+ static POOL_STATUS CheckMd5Auth(char *username);
71
+
72
+ const char* presto_server = NULL;
73
+ const char* presto_user = NULL;
74
+ const char* presto_catalog = NULL;
75
+ const char* presto_schema = NULL;
76
+ const char* presto_external_auth_prog = NULL;
77
+
78
+ static bool prestogres_hba_set_session_info(const char* key, const char* value);
79
+ static void prestogres_hba_parse_arg(const char* arg);
80
+ static POOL_STATUS pool_prestogres_hba_auth_md5(POOL_CONNECTION *frontend);
81
+ static POOL_STATUS pool_prestogres_hba_auth_external(POOL_CONNECTION *frontend);
82
+
83
+ static char *recv_password_packet(POOL_CONNECTION *frontend);
84
+
85
+ #ifdef USE_PAM
86
+ #ifdef HAVE_PAM_PAM_APPL_H
87
+ #include <pam/pam_appl.h>
88
+ #endif
89
+ #ifdef HAVE_SECURITY_PAM_APPL_H
90
+ #include <security/pam_appl.h>
91
+ #endif
92
+
93
+ #define PGPOOL_PAM_SERVICE "pgpool" /* Service name passed to PAM */
94
+
95
+ static POOL_STATUS CheckPAMAuth(POOL_CONNECTION *frontend, char *user, char *password);
96
+ static int pam_passwd_conv_proc(int num_msg, const struct pam_message ** msg, struct pam_response ** resp, void *appdata_ptr);
97
+
98
+ static struct pam_conv pam_passw_conv = {
99
+ &pam_passwd_conv_proc,
100
+ NULL
101
+ };
102
+
103
+ static char *pam_passwd = NULL; /* Workaround for Solaris 2.6 brokenness */
104
+ static POOL_CONNECTION *pam_frontend_kludge; /* Workaround for passing
105
+ * POOL_CONNECTION *frontend
106
+ * into pam_passwd_conv_proc */
107
+ #endif /* USE_PAM */
108
+
109
+
110
+ /*
111
+ * read in hba config file
112
+ */
113
+ int load_hba(char *hbapath)
114
+ {
115
+ FILE *file;
116
+
117
+ POOL_MEMORY_POOL *old_context;
118
+ if (hba_memory_context == NULL)
119
+ {
120
+ hba_memory_context = pool_memory_create(PARSER_BLOCK_SIZE);
121
+ if (hba_memory_context == NULL)
122
+ {
123
+ pool_error("load_hba: pool_memory_create() failed");
124
+ return -1;
125
+ }
126
+ }
127
+ /* switch memory context */
128
+ old_context = pool_memory_context_switch_to(hba_memory_context);
129
+
130
+ if (hba_lines || hba_line_nums)
131
+ free_lines(&hba_lines, &hba_line_nums);
132
+
133
+ file = fopen(hbapath, "r");
134
+ if (!file)
135
+ {
136
+ pool_error("could not open \"%s\". reason: %s",
137
+ hbapath, strerror(errno));
138
+ pool_memory_delete(hba_memory_context, 0);
139
+
140
+ /* switch to old memory context */
141
+ pool_memory_context_switch_to(old_context);
142
+
143
+ return -1;
144
+ }
145
+
146
+ pool_debug("loading \"%s\" for client authentication configuration file",
147
+ hbapath);
148
+
149
+ tokenize_file(hbapath, file, &hba_lines, &hba_line_nums);
150
+ fclose(file);
151
+
152
+ hbaFileName = pstrdup(hbapath);
153
+
154
+ /* switch to old memory context */
155
+ pool_memory_context_switch_to(old_context);
156
+
157
+ return 0;
158
+ }
159
+
160
+
161
+ /*
162
+ * do frontend <-> pgpool authentication based on pool_hba.conf
163
+ */
164
+ void ClientAuthentication(POOL_CONNECTION *frontend)
165
+ {
166
+ POOL_STATUS status = POOL_ERROR;
167
+
168
+ if (! hba_getauthmethod(frontend))
169
+ {
170
+ pool_error("missing or erroneous pool_hba.conf file");
171
+ pool_send_error_message(frontend, frontend->protoVersion, "XX000",
172
+ "missing or erroneous pool_hba.conf file", "",
173
+ "See pgpool log for details.", __FILE__, __LINE__);
174
+ close_all_backend_connections();
175
+ /*
176
+ * use exit(2) since this is not so fatal. other entries in
177
+ * pool_hba.conf may be valid, so treat it as reject.
178
+ */
179
+ child_exit(2);
180
+ }
181
+
182
+ switch (frontend->auth_method)
183
+ {
184
+ case uaReject:
185
+ {
186
+ /*
187
+ * This could have come from an explicit "reject" entry in
188
+ * pool_hba.conf, but more likely it means there was no matching
189
+ * entry. Take pity on the poor user and issue a helpful
190
+ * error message. NOTE: this is not a security breach,
191
+ * because all the info reported here is known at the frontend
192
+ * and must be assumed known to bad guys. We're merely helping
193
+ * out the less clueful good guys.
194
+ */
195
+ char hostinfo[NI_MAXHOST];
196
+ char *errmessage;
197
+ int messagelen;
198
+
199
+ getnameinfo_all(&frontend->raddr.addr, frontend->raddr.salen,
200
+ hostinfo, sizeof(hostinfo),
201
+ NULL, 0,
202
+ NI_NUMERICHOST);
203
+
204
+ messagelen = sizeof(hostinfo) +
205
+ strlen(frontend->username) + strlen(frontend->database) + 80;
206
+ if ((errmessage = (char *)malloc(messagelen+1)) == NULL)
207
+ {
208
+ pool_error("ClientAuthentication: malloc failed: %s", strerror(errno));
209
+ child_exit(1);
210
+ }
211
+
212
+ #ifdef USE_SSL
213
+ snprintf(errmessage, messagelen+7, /* +7 is for "SSL off" */
214
+ "no pool_hba.conf entry for host \"%s\", user \"%s\", database \"%s\", %s",
215
+ hostinfo, frontend->username, frontend->database,
216
+ frontend->ssl ? "SSL on" : "SSL off");
217
+ #else
218
+ snprintf(errmessage, messagelen,
219
+ "no pool_hba.conf entry for host \"%s\", user \"%s\", database \"%s\"",
220
+ hostinfo, frontend->username, frontend->database);
221
+ #endif
222
+ pool_error("%s", errmessage);
223
+ pool_send_error_message(frontend, frontend->protoVersion, "XX000", errmessage,
224
+ "", "", __FILE__, __LINE__);
225
+
226
+ free(errmessage);
227
+ break;
228
+ }
229
+
230
+ /* case uaKrb4: */
231
+ /* break; */
232
+
233
+ /* case uaKrb5: */
234
+ /* break; */
235
+
236
+ /* case uaIdent: */
237
+ /* break; */
238
+
239
+ case uaMD5:
240
+ status = CheckMd5Auth(frontend->username);
241
+ break;
242
+
243
+ /* case uaCrypt: */
244
+ /* break; */
245
+
246
+ /* case uaPassword: */
247
+ /* break; */
248
+
249
+ #ifdef USE_PAM
250
+ case uaPAM:
251
+ pam_frontend_kludge = frontend;
252
+ status = CheckPAMAuth(frontend, frontend->username, "");
253
+ break;
254
+ #endif /* USE_PAM */
255
+ case uaPrestogresMD5:
256
+ status = pool_prestogres_hba_auth_md5(frontend);
257
+ break;
258
+ case uaPrestogresExternal:
259
+ status = pool_prestogres_hba_auth_external(frontend);
260
+ break;
261
+
262
+ case uaTrust:
263
+ status = POOL_CONTINUE;
264
+ break;
265
+ }
266
+
267
+ if (status == POOL_CONTINUE)
268
+ sendAuthRequest(frontend, AUTH_REQ_OK);
269
+ else if (status != POOL_CONTINUE)
270
+ auth_failed(frontend);
271
+ }
272
+
273
+
274
+ static void sendAuthRequest(POOL_CONNECTION *frontend, AuthRequest areq)
275
+ {
276
+ int wsize; /* number of bytes to write */
277
+ int areq_nbo; /* areq in network byte order */
278
+
279
+ /*
280
+ * If AUTH_REQ_OK, then frontend is OK to connect __with_pgpool__.
281
+ * Do not send 'R' to the frontend, he still needs to authenticate
282
+ * himself with the backend.
283
+ */
284
+ if (areq == AUTH_REQ_OK)
285
+ return;
286
+
287
+ /* request a password */
288
+ pool_write(frontend, "R", 1);
289
+
290
+ if (frontend->protoVersion == PROTO_MAJOR_V3)
291
+ {
292
+ /* if (areq == AUTH_REQ_MD5) */
293
+ /* wsize = htonl(sizeof(int)*2+4); */
294
+ /* else if (areq == AUTH_REQ_CRYPT) */
295
+ /* wsize = htonl(sizeof(int)*2+2); */
296
+ /* else */
297
+ wsize = htonl(sizeof(int)*2);
298
+ pool_write(frontend, &wsize, sizeof(int));
299
+ }
300
+
301
+ areq_nbo = htonl(areq);
302
+ pool_write(frontend, &areq_nbo, sizeof(int));
303
+
304
+ /* Add the salt for encrypted passwords. */
305
+ /* if (areq == AUTH_REQ_MD5) */
306
+ /* pq_sendbytes(&buf, port->md5Salt, 4); */
307
+ /* else if (areq == AUTH_REQ_CRYPT) */
308
+ /* pq_sendbytes(&buf, port->cryptSalt, 2); */
309
+
310
+ pool_flush(frontend);
311
+ }
312
+
313
+
314
+ /*
315
+ * Collect password response packet from frontend.
316
+ *
317
+ * Returns NULL if couldn't get password, else malloc'd string.
318
+ */
319
+ static char *recv_password_packet(POOL_CONNECTION *frontend)
320
+ {
321
+ int rsize;
322
+ char *passwd;
323
+ char *returnVal;
324
+
325
+ if (frontend->protoVersion == PROTO_MAJOR_V3)
326
+ {
327
+ /* Expect 'p' message type */
328
+ char kind;
329
+
330
+ if (pool_read(frontend, &kind, 1) < 0)
331
+ return NULL;
332
+
333
+ if (kind != 'p')
334
+ {
335
+ pool_error("expected password response, got message type %c",
336
+ kind);
337
+ return NULL; /* bad message type */
338
+ }
339
+ }
340
+ /* pre-3.0 protocol does not send a message type */
341
+
342
+ if (pool_read(frontend, &rsize, sizeof(int)) < 0)
343
+ return NULL;
344
+
345
+ rsize = ntohl(rsize) - 4;
346
+ passwd = pool_read2(frontend, rsize); /* retrieve password */
347
+ if (passwd == NULL)
348
+ return NULL;
349
+
350
+ /* Do not echo password to logs, for security. */
351
+ pool_debug("received password packet from frontend for pgpool's HBA");
352
+
353
+ /*
354
+ * Return the received string. Note we do not attempt to do any
355
+ * character-set conversion on it; since we don't yet know the
356
+ * client's encoding, there wouldn't be much point.
357
+ */
358
+ returnVal = strdup(passwd);
359
+ if (returnVal == NULL)
360
+ {
361
+ pool_error("recv_password_packet: strdup failed: %s", strerror(errno));
362
+ exit(1);
363
+ }
364
+ return returnVal;
365
+ }
366
+
367
+ /*
368
+ * Tell the user the authentication failed.
369
+ */
370
+ static void auth_failed(POOL_CONNECTION *frontend)
371
+ {
372
+ bool send_error_to_frontend = true;
373
+ int messagelen;
374
+ char *errmessage;
375
+
376
+ messagelen = strlen(frontend->username) + 100;
377
+ if ((errmessage = (char *)malloc(messagelen+1)) == NULL)
378
+ {
379
+ pool_error("auth_failed: malloc failed: %s", strerror(errno));
380
+ child_exit(1);
381
+ }
382
+
383
+ switch (frontend->auth_method)
384
+ {
385
+ case uaReject:
386
+ snprintf(errmessage, messagelen,
387
+ "authentication with pgpool failed for user \"%s\": host rejected",
388
+ frontend->username);
389
+ /*
390
+ * if uaReject, frontend should have received 'E' and disconnected already.
391
+ */
392
+ send_error_to_frontend = false;
393
+ break;
394
+ /* case uaKrb4: */
395
+ /* snprintf(errmessage, messagelen, */
396
+ /* "Kerberos 4 authentication with pgpool failed for user \"%s\"", */
397
+ /* frontend->username); */
398
+ /* break; */
399
+ /* case uaKrb5: */
400
+ /* snprintf(errmessage, messagelen, */
401
+ /* "Kerberos 5 authentication with pgpool failed for user \"%s\"", */
402
+ /* frontend->username); */
403
+ /* break; */
404
+ case uaTrust:
405
+ snprintf(errmessage, messagelen,
406
+ "\"trust\" authentication with pgpool failed for user \"%s\"",
407
+ frontend->username);
408
+ break;
409
+ /* case uaIdent: */
410
+ /* snprintf(errmessage, messagelen, */
411
+ /* "Ident authentication with pgpool failed for user \"%s\"", */
412
+ /* frontend->username); */
413
+ /* break; */
414
+ case uaMD5:
415
+ snprintf(errmessage, messagelen,
416
+ "\"MD5\" authentication with pgpool failed for user \"%s\"",
417
+ frontend->username);
418
+ break;
419
+
420
+ /* case uaCrypt: */
421
+ /* case uaPassword: */
422
+ /* snprintf(errmessage, messagelen, */
423
+ /* "password authentication with pgpool failed for user \"%s\"", */
424
+ /* frontend->username); */
425
+ /* break; */
426
+ #ifdef USE_PAM
427
+ case uaPAM:
428
+ snprintf(errmessage, messagelen,
429
+ "PAM authentication with pgpool failed for user \"%s\"",
430
+ frontend->username);
431
+ break;
432
+ #endif /* USE_PAM */
433
+ case uaPrestogresMD5:
434
+ snprintf(errmessage, messagelen,
435
+ "\"MD5\" authentication with pgpool failed for user \"%s\"",
436
+ frontend->username);
437
+ break;
438
+ case uaPrestogresExternal:
439
+ snprintf(errmessage, messagelen,
440
+ "\"external\" authentication with pgpool failed for user \"%s\"",
441
+ frontend->username);
442
+ break;
443
+ default:
444
+ snprintf(errmessage, messagelen,
445
+ "authentication with pgpool failed for user \"%s\": invalid authentication method",
446
+ frontend->username);
447
+ break;
448
+ }
449
+
450
+ pool_error("%s", errmessage);
451
+ if (send_error_to_frontend)
452
+ pool_send_error_message(frontend, frontend->protoVersion, "XX000", errmessage,
453
+ "", "", __FILE__, __LINE__);
454
+
455
+ /*
456
+ * don't need to free(errmessage). I will just kill myself.
457
+ */
458
+ close_all_backend_connections();
459
+ child_exit(2);
460
+ }
461
+
462
+
463
+ /*
464
+ * Close all of the cached backend connections.
465
+ *
466
+ * This is exactly the same as send_frontend_exits() in child.c.
467
+ */
468
+ static void close_all_backend_connections(void)
469
+ {
470
+ int i;
471
+ POOL_CONNECTION_POOL *p = pool_connection_pool;
472
+
473
+ #ifdef HAVE_SIGPROCMASK
474
+ sigset_t oldmask;
475
+ #else
476
+ int oldmask;
477
+ #endif
478
+
479
+ POOL_SETMASK2(&BlockSig, &oldmask);
480
+
481
+ for (i=0;i<pool_config->max_pool;i++, p++)
482
+ {
483
+ if (!MASTER_CONNECTION(p))
484
+ continue;
485
+ if (MASTER_CONNECTION(p)->sp->user == NULL)
486
+ continue;
487
+ pool_send_frontend_exits(p);
488
+ }
489
+
490
+ POOL_SETMASK(&oldmask);
491
+ }
492
+
493
+
494
+ /*
495
+ * Determine what authentication method should be used when accessing database
496
+ * "database" from frontend "raddr", user "user". Return the method and
497
+ * an optional argument (stored in fields of *frontend), and true for success.
498
+ *
499
+ * Note that false indicates a problem with the hba config file.
500
+ * If the file is OK but does not contain any entry matching the request,
501
+ * we return true and method = uaReject.
502
+ */
503
+ static bool hba_getauthmethod(POOL_CONNECTION *frontend)
504
+ {
505
+ if (check_hba(frontend))
506
+ return true;
507
+ else
508
+ return false;
509
+ }
510
+
511
+
512
+ /*
513
+ * Scan the (pre-parsed) hba file line by line, looking for a match
514
+ * to the port's connection request.
515
+ */
516
+ static bool check_hba(POOL_CONNECTION *frontend)
517
+ {
518
+ bool found_entry = false;
519
+ bool error = false;
520
+ ListCell *line;
521
+ ListCell *line_num;
522
+
523
+ forboth(line, hba_lines, line_num, hba_line_nums)
524
+ {
525
+ parse_hba(lfirst(line), lfirst_int(line_num),
526
+ frontend, &found_entry, &error);
527
+ if (found_entry || error)
528
+ break;
529
+ }
530
+
531
+ if (!error)
532
+ {
533
+ /* If no matching entry was found, synthesize 'reject' entry. */
534
+ if (!found_entry)
535
+ frontend->auth_method = uaReject;
536
+ return true;
537
+ }
538
+ else
539
+ return false;
540
+ }
541
+
542
+
543
+ /*
544
+ * Process one line from the hba config file.
545
+ *
546
+ * See if it applies to a connection from a frontend with IP address
547
+ * frontend->raddr to a database named frontend->database. If so, return
548
+ * *found_p true and fill in the auth arguments into the appropriate
549
+ * frontend fields. If not, leave *found_p as it was. If the record has
550
+ * a syntax error, return *error_p true, after issuing a message to the
551
+ * log. If no error, leave *error_p as it was.
552
+ */
553
+ static void parse_hba(List *line, int line_num, POOL_CONNECTION *frontend,
554
+ bool *found_p, bool *error_p)
555
+ {
556
+ char *token;
557
+ char *db, *db_tmp;
558
+ char *user, *user_tmp;
559
+ struct addrinfo *gai_result;
560
+ struct addrinfo hints;
561
+ int ret;
562
+ struct sockaddr_storage addr;
563
+ struct sockaddr_storage mask;
564
+ char *cidr_slash;
565
+ ListCell *line_item;
566
+
567
+ line_item = list_head(line);
568
+ /* Check the record type. */
569
+ token = lfirst(line_item);
570
+ if (strcmp(token, "local") == 0)
571
+ {
572
+ /* Get the database. */
573
+ line_item = lnext(line_item);
574
+ if (!line_item)
575
+ goto hba_syntax;
576
+ db = lfirst(line_item);
577
+
578
+ /* Get the user. */
579
+ line_item = lnext(line_item);
580
+ if (!line_item)
581
+ goto hba_syntax;
582
+ user = lfirst(line_item);
583
+
584
+ line_item = lnext(line_item);
585
+ if (!line_item)
586
+ goto hba_syntax;
587
+
588
+ /* Read the rest of the line. */
589
+ parse_hba_auth(&line_item, &frontend->auth_method,
590
+ &frontend->auth_arg, error_p);
591
+ if (*error_p)
592
+ goto hba_syntax;
593
+
594
+ /* Disallow auth methods that always need TCP/IP sockets to work */
595
+ /*
596
+ if (frontend->auth_method == uaKrb4 ||
597
+ frontend->auth_method == uaKrb5)
598
+ goto hba_syntax;
599
+ */
600
+
601
+ /* Does not match if connection isn't AF_UNIX */
602
+ if (!IS_AF_UNIX(frontend->raddr.addr.ss_family))
603
+ return;
604
+ }
605
+ else if (strcmp(token, "host") == 0
606
+ || strcmp(token, "hostssl") == 0
607
+ || strcmp(token, "hostnossl") == 0)
608
+ {
609
+ if (token[4] == 's') /* "hostssl" */
610
+ {
611
+ #ifdef USE_SSL
612
+ /* Record does not match if we are not on an SSL connection */
613
+ if (!frontend->ssl)
614
+ return;
615
+
616
+ /* Placeholder to require specific SSL level, perhaps? */
617
+ /* Or a client certificate */
618
+
619
+ /* Since we were on SSL, proceed as with normal 'host' mode */
620
+ #else
621
+ /* We don't accept this keyword at all if no SSL support */
622
+ goto hba_syntax;
623
+ #endif
624
+ }
625
+ #ifdef USE_SSL
626
+ else if (token[4] == 'n') /* "hostnossl" */
627
+ {
628
+ /* Record does not match if we are on an SSL connection */
629
+ if (frontend->ssl)
630
+ return;
631
+ }
632
+ #endif
633
+
634
+ /* Get the database. */
635
+ line_item = lnext(line_item);
636
+ if (!line_item)
637
+ goto hba_syntax;
638
+ db = lfirst(line_item);
639
+
640
+ /* Get the user. */
641
+ line_item = lnext(line_item);
642
+ if (!line_item)
643
+ goto hba_syntax;
644
+ user = lfirst(line_item);
645
+
646
+ /* Read the IP address field. (with or without CIDR netmask) */
647
+ line_item = lnext(line_item);
648
+ if (!line_item)
649
+ goto hba_syntax;
650
+ token = lfirst(line_item);
651
+
652
+ /* Check if it has a CIDR suffix and if so isolate it */
653
+ cidr_slash = strchr(token, '/');
654
+ if (cidr_slash)
655
+ *cidr_slash = '\0';
656
+
657
+ /* Get the IP address either way */
658
+ hints.ai_flags = AI_NUMERICHOST;
659
+ hints.ai_family = PF_UNSPEC;
660
+ hints.ai_socktype = 0;
661
+ hints.ai_protocol = 0;
662
+ hints.ai_addrlen = 0;
663
+ hints.ai_canonname = NULL;
664
+ hints.ai_addr = NULL;
665
+ hints.ai_next = NULL;
666
+
667
+ ret = getaddrinfo_all(token, NULL, &hints, &gai_result);
668
+ if (ret || !gai_result)
669
+ {
670
+ pool_log("invalid IP address \"%s\" in file \"%s\" line %d: %s",
671
+ token, hbaFileName, line_num, gai_strerror(ret));
672
+ if (cidr_slash)
673
+ *cidr_slash = '/';
674
+ if (gai_result)
675
+ freeaddrinfo_all(hints.ai_family, gai_result);
676
+ goto hba_other_error;
677
+ }
678
+
679
+ if (cidr_slash)
680
+ *cidr_slash = '/';
681
+
682
+ memcpy(&addr, gai_result->ai_addr, gai_result->ai_addrlen);
683
+ freeaddrinfo_all(hints.ai_family, gai_result);
684
+
685
+ /* Get the netmask */
686
+ if (cidr_slash)
687
+ {
688
+ if (SockAddr_cidr_mask(&mask, cidr_slash + 1, addr.ss_family) < 0)
689
+ goto hba_syntax;
690
+ }
691
+ else
692
+ {
693
+ /* Read the mask field. */
694
+ line_item = lnext(line_item);
695
+ if (!line_item)
696
+ goto hba_syntax;
697
+ token = lfirst(line_item);
698
+
699
+ ret = getaddrinfo_all(token, NULL, &hints, &gai_result);
700
+ if (ret || !gai_result)
701
+ {
702
+ pool_log("invalid IP mask \"%s\" in file \"%s\" line %d: %s",
703
+ token, hbaFileName, line_num, gai_strerror(ret));
704
+ if (gai_result)
705
+ freeaddrinfo_all(hints.ai_family, gai_result);
706
+ goto hba_other_error;
707
+ }
708
+
709
+ memcpy(&mask, gai_result->ai_addr, gai_result->ai_addrlen);
710
+ freeaddrinfo_all(hints.ai_family, gai_result);
711
+
712
+ if (addr.ss_family != mask.ss_family)
713
+ {
714
+ pool_log("IP address and mask do not match in file \"%s\" line %d",
715
+ hbaFileName, line_num);
716
+ goto hba_other_error;
717
+ }
718
+ }
719
+
720
+ if (addr.ss_family != frontend->raddr.addr.ss_family)
721
+ {
722
+ /*
723
+ * Wrong address family. We allow only one case: if the file
724
+ * has IPv4 and the port is IPv6, promote the file address to
725
+ * IPv6 and try to match that way.
726
+ */
727
+ #ifdef HAVE_IPV6
728
+ if (addr.ss_family == AF_INET && frontend->raddr.addr.ss_family == AF_INET6)
729
+ {
730
+ promote_v4_to_v6_addr(&addr);
731
+ promote_v4_to_v6_mask(&mask);
732
+ }
733
+ else
734
+ #endif /* HAVE_IPV6 */
735
+ {
736
+ /* Line doesn't match client port, so ignore it. */
737
+ return;
738
+ }
739
+ }
740
+
741
+ /* Ignore line if client port is not in the matching addr range. */
742
+ if (!rangeSockAddr(&frontend->raddr.addr, &addr, &mask))
743
+ return;
744
+
745
+ /* Read the rest of the line. */
746
+ line_item = lnext(line_item);
747
+ if (!line_item)
748
+ goto hba_syntax;
749
+ parse_hba_auth(&line_item, &frontend->auth_method,
750
+ &frontend->auth_arg, error_p);
751
+ if (*error_p)
752
+ goto hba_syntax;
753
+ }
754
+ else
755
+ goto hba_syntax;
756
+
757
+ /* Does the entry match database and user? */
758
+ /*
759
+ * duplicate db and username since strtok() in check_db() and check_user()
760
+ * will override '\001' with '\0'.
761
+ */
762
+ db_tmp = strdup(db);
763
+ if (db_tmp == NULL)
764
+ {
765
+ pool_error("parse_hba: strdup failed: %s", strerror(errno));
766
+ exit(1);
767
+ }
768
+ user_tmp = strdup(user);
769
+ if (user_tmp == NULL)
770
+ {
771
+ pool_error("parse_hba: strdup failed: %s", strerror(errno));
772
+ exit(1);
773
+ }
774
+ if (!check_db(frontend->database, frontend->username, db_tmp))
775
+ return;
776
+ if (!check_user(frontend->username, user_tmp))
777
+ return;
778
+ free(db_tmp);
779
+ free(user_tmp);
780
+
781
+ /* Success */
782
+ *found_p = true;
783
+ return;
784
+
785
+ hba_syntax:
786
+ if (line_item)
787
+ pool_log("invalid entry in file \"%s\" at line %d, token \"%s\"",
788
+ hbaFileName, line_num, (char *) lfirst(line_item));
789
+ else
790
+ pool_log("missing field in file \"%s\" at end of line %d",
791
+ hbaFileName, line_num);
792
+
793
+ /* Come here if suitable message already logged */
794
+ hba_other_error:
795
+ *error_p = true;
796
+ }
797
+
798
+
799
+ /*
800
+ * Scan the rest of a host record (after the mask field)
801
+ * and return the interpretation of it as *userauth_p, *auth_arg_p, and
802
+ * *error_p. *line_item points to the next token of the line, and is
803
+ * advanced over successfully-read tokens.
804
+ */
805
+ static void parse_hba_auth(ListCell **line_item, UserAuth *userauth_p,
806
+ char **auth_arg_p, bool *error_p)
807
+ {
808
+ char *token;
809
+
810
+ *auth_arg_p = NULL;
811
+
812
+ if (!*line_item)
813
+ {
814
+ *error_p = true;
815
+ return;
816
+ }
817
+
818
+ token = lfirst(*line_item);
819
+ if (strcmp(token, "trust") == 0)
820
+ *userauth_p = uaTrust;
821
+ /*
822
+ else if (strcmp(token, "ident") == 0)
823
+ *userauth_p = uaIdent;
824
+ else if (strcmp(token, "password") == 0)
825
+ *userauth_p = uaPassword;
826
+ else if (strcmp(token, "krb4") == 0)
827
+ *userauth_p = uaKrb4;
828
+ else if (strcmp(token, "krb5") == 0)
829
+ *userauth_p = uaKrb5;
830
+ */
831
+ else if (strcmp(token, "reject") == 0)
832
+ *userauth_p = uaReject;
833
+ else if (strcmp(token, "md5") == 0)
834
+ *userauth_p = uaMD5;
835
+ /*
836
+ else if (strcmp(token, "crypt") == 0)
837
+ *userauth_p = uaCrypt;
838
+ */
839
+ #ifdef USE_PAM
840
+ else if (strcmp(token, "pam") == 0)
841
+ *userauth_p = uaPAM;
842
+ #endif /* USE_PAM */
843
+ else if (strcmp(token, "prestogres_md5") == 0)
844
+ *userauth_p = uaPrestogresMD5;
845
+ else if (strcmp(token, "prestogres_external") == 0)
846
+ *userauth_p = uaPrestogresExternal;
847
+ else
848
+ {
849
+ *error_p = true;
850
+ return;
851
+ }
852
+ *line_item = lnext(*line_item);
853
+
854
+ /* Get the authentication argument token, if any */
855
+ if (*line_item)
856
+ {
857
+ token = lfirst(*line_item);
858
+ *auth_arg_p = strdup(token);
859
+ if (*auth_arg_p == NULL)
860
+ {
861
+ pool_error("parse_hba_auth: strdup failed: %s", strerror(errno));
862
+ exit(1);
863
+ }
864
+ *line_item = lnext(*line_item);
865
+ /* If there is more on the line, it is an error */
866
+ if (*line_item)
867
+ *error_p = true;
868
+ }
869
+ }
870
+
871
+
872
+ /*
873
+ * Check comma user list for a specific user, handle group names.
874
+ */
875
+ static bool check_user(char *user, char *param_str)
876
+ {
877
+ char *tok;
878
+
879
+ for (tok = strtok(param_str, MULTI_VALUE_SEP);
880
+ tok != NULL; tok = strtok(NULL, MULTI_VALUE_SEP))
881
+ {
882
+ if (tok[0] == '+')
883
+ {
884
+ /*
885
+ * pgpool cannot accept groups. commented lines below are the
886
+ * original code.
887
+ */
888
+ pool_error("group token \"+\" is not supported in pgpool");
889
+ return false;
890
+ /* if (check_group(tok + 1, user)) */
891
+ /* return true; */
892
+ }
893
+ else if (strcmp(tok, user) == 0 || strcmp(tok, "all\n") == 0)
894
+ return true;
895
+ }
896
+
897
+ return false;
898
+ }
899
+
900
+
901
+ /*
902
+ * Check to see if db/user combination matches param string.
903
+ */
904
+ static bool check_db(char *dbname, char *user, char *param_str)
905
+ {
906
+ char *tok;
907
+
908
+ for (tok = strtok(param_str, MULTI_VALUE_SEP);
909
+ tok != NULL; tok = strtok(NULL, MULTI_VALUE_SEP))
910
+ {
911
+ if (strcmp(tok, "all\n") == 0)
912
+ return true;
913
+ else if (strcmp(tok, "sameuser\n") == 0)
914
+ {
915
+ if (strcmp(dbname, user) == 0)
916
+ return true;
917
+ }
918
+ else if (strcmp(tok, "samegroup\n") == 0)
919
+ {
920
+ /*
921
+ * pgpool cannot accept groups. commented lines below are the
922
+ * original code.
923
+ */
924
+ pool_error("group token \"samegroup\" is not supported in pgpool");
925
+ return false;
926
+ /* if (check_group(dbname, user)) */
927
+ /* return true; */
928
+ }
929
+ else if (strcmp(tok, dbname) == 0)
930
+ return true;
931
+ }
932
+
933
+ return false;
934
+ }
935
+
936
+
937
+ /*
938
+ * tokenize the given file, storing the resulting data into two lists:
939
+ * a list of sublists, each sublist containing the tokens in a line of
940
+ * the file, and a list of line numbers.
941
+ *
942
+ * filename must be the absolute path to the target file.
943
+ */
944
+ static void tokenize_file(const char *filename, FILE *file,
945
+ List **lines, List **line_nums)
946
+ {
947
+ List *current_line = NIL;
948
+ int line_number = 1;
949
+ char *buf;
950
+
951
+ *lines = *line_nums = NIL;
952
+
953
+ while (!feof(file))
954
+ {
955
+ buf = next_token_expand(filename, file);
956
+
957
+ /* add token to list, unless we are at EOL or comment start */
958
+ if (buf[0])
959
+ {
960
+ if (current_line == NIL)
961
+ {
962
+ /* make a new line List, record its line number */
963
+ current_line = lappend(current_line, buf);
964
+ *lines = lappend(*lines, current_line);
965
+ *line_nums = lappend_int(*line_nums, line_number);
966
+ }
967
+ else
968
+ {
969
+ /* append token to current line's list */
970
+ current_line = lappend(current_line, buf);
971
+ }
972
+ }
973
+ else
974
+ {
975
+ /* we are at real or logical EOL, so force a new line List */
976
+ current_line = NIL;
977
+ /* Advance line number whenever we reach EOL */
978
+ line_number++;
979
+ /* Don't forget to free the next_token_expand result */
980
+ free(buf);
981
+ }
982
+ }
983
+ }
984
+
985
+
986
+ static char * tokenize_inc_file(const char *outer_filename,
987
+ const char *inc_filename)
988
+ {
989
+ char *inc_fullname;
990
+ FILE *inc_file;
991
+ List *inc_lines;
992
+ List *inc_line_nums;
993
+ ListCell *line;
994
+ char *comma_str;
995
+
996
+ if (is_absolute_path(inc_filename))
997
+ {
998
+ /* absolute path is taken as-is */
999
+ inc_fullname = strdup(inc_filename);
1000
+ if (inc_fullname == NULL)
1001
+ {
1002
+ pool_error("tokenize_inc_file: strdup failed: %s", strerror(errno));
1003
+ exit(1);
1004
+ }
1005
+ }
1006
+ else
1007
+ {
1008
+ /* relative path is relative to dir of calling file */
1009
+ inc_fullname = (char *)malloc(strlen(outer_filename) + 1 +
1010
+ strlen(inc_filename) + 1);
1011
+ if (inc_fullname == NULL)
1012
+ {
1013
+ pool_error("tokenize_inc_file: malloc failed: %s", strerror(errno));
1014
+ exit(1);
1015
+ }
1016
+ strcpy(inc_fullname, outer_filename);
1017
+ get_parent_directory(inc_fullname);
1018
+ join_path_components(inc_fullname, inc_fullname, inc_filename);
1019
+ canonicalize_path(inc_fullname);
1020
+ }
1021
+
1022
+ inc_file = fopen(inc_fullname, "r");
1023
+ if (inc_file == NULL)
1024
+ {
1025
+ char *returnVal;
1026
+
1027
+ pool_error("could not open secondary authentication file \"@%s\" as \"%s\": reason: %s",
1028
+ inc_filename, inc_fullname, strerror(errno));
1029
+ free(inc_fullname);
1030
+
1031
+ /* return single space, it matches nothing */
1032
+ returnVal = strdup(" ");
1033
+ if (returnVal == NULL)
1034
+ {
1035
+ pool_error("tokenize_inc_file: malloc failed: %s", strerror(errno));
1036
+ exit(1);
1037
+ }
1038
+ return returnVal;
1039
+ }
1040
+
1041
+ /* There is possible recursion here if the file contains @ */
1042
+ tokenize_file(inc_fullname, inc_file, &inc_lines, &inc_line_nums);
1043
+
1044
+ /*FreeFile(inc_file);*/
1045
+ fclose(inc_file);
1046
+ free(inc_fullname);
1047
+
1048
+ /* Create comma-separated string from List */
1049
+ comma_str = strdup("");
1050
+ if (comma_str == NULL)
1051
+ {
1052
+ pool_error("tokenize_inc_file: strdup failed: %s", strerror(errno));
1053
+ exit(1);
1054
+ }
1055
+ foreach(line, inc_lines)
1056
+ {
1057
+ List *token_list = (List *) lfirst(line);
1058
+ ListCell *token;
1059
+
1060
+ foreach(token, token_list)
1061
+ {
1062
+ int oldlen = strlen(comma_str);
1063
+ int needed;
1064
+
1065
+ needed = oldlen + strlen(lfirst(token)) + 1;
1066
+ if (oldlen > 0)
1067
+ needed++;
1068
+ comma_str = realloc(comma_str, needed);
1069
+ if (comma_str == NULL)
1070
+ {
1071
+ pool_error("tokenize_inc_file: realloc failed: %s", strerror(errno));
1072
+ exit(1);
1073
+ }
1074
+ if (oldlen > 0)
1075
+ strcat(comma_str, MULTI_VALUE_SEP);
1076
+ strcat(comma_str, lfirst(token));
1077
+ }
1078
+ }
1079
+
1080
+ free_lines(&inc_lines, &inc_line_nums);
1081
+
1082
+ /* if file is empty, return single space rather than empty string */
1083
+ if (strlen(comma_str) == 0)
1084
+ {
1085
+ char *returnVal;
1086
+
1087
+ free(comma_str);
1088
+ returnVal = strdup(" ");
1089
+ if (returnVal == NULL)
1090
+ {
1091
+ pool_error("tokenize_inc_file: strdup failed: %s", strerror(errno));
1092
+ exit(1);
1093
+ }
1094
+ return returnVal;
1095
+ }
1096
+
1097
+ return comma_str;
1098
+ }
1099
+
1100
+
1101
+ /*
1102
+ * isblank() exists in the ISO C99 spec, but it's not very portable yet,
1103
+ * so provide our own version.
1104
+ */
1105
+ static bool pg_isblank(const char c)
1106
+ {
1107
+ return c == ' ' || c == '\t' || c == '\r';
1108
+ }
1109
+
1110
+
1111
+ /*
1112
+ * Tokenize file and handle file inclusion and comma lists. We have
1113
+ * to break apart the commas to expand any file names then
1114
+ * reconstruct with commas.
1115
+ *
1116
+ * The result is always a malloc'd string. If it's zero-length then
1117
+ * we have reached EOL.
1118
+ */
1119
+ static char * next_token_expand(const char *filename, FILE *file)
1120
+ {
1121
+ char buf[MAX_TOKEN];
1122
+ char *comma_str;
1123
+ bool trailing_comma;
1124
+ char *incbuf;
1125
+ int needed;
1126
+
1127
+ comma_str = strdup("");
1128
+ if (comma_str == NULL)
1129
+ {
1130
+ pool_error("next_token_expand: strdup failed: %s", strerror(errno));
1131
+ exit(1);
1132
+ }
1133
+
1134
+ do
1135
+ {
1136
+ next_token(file, buf, sizeof(buf));
1137
+ if (!buf[0])
1138
+ break;
1139
+
1140
+ if (buf[strlen(buf) - 1] == ',')
1141
+ {
1142
+ trailing_comma = true;
1143
+ buf[strlen(buf) - 1] = '\0';
1144
+ }
1145
+ else
1146
+ trailing_comma = false;
1147
+
1148
+ /* Is this referencing a file? */
1149
+ if (buf[0] == '@')
1150
+ incbuf = tokenize_inc_file(filename, buf + 1);
1151
+ else
1152
+ {
1153
+ incbuf = strdup(buf);
1154
+ if (incbuf == NULL)
1155
+ {
1156
+ pool_error("next_token_expand: strdup failed: %s", strerror(errno));
1157
+ exit(1);
1158
+ }
1159
+ }
1160
+
1161
+ needed = strlen(comma_str) + strlen(incbuf) + 1;
1162
+ if (trailing_comma)
1163
+ needed++;
1164
+ comma_str = realloc(comma_str, needed);
1165
+ if (comma_str == NULL)
1166
+ {
1167
+ pool_error("next_token_expand: realloc failed: %s", strerror(errno));
1168
+ exit(1);
1169
+ }
1170
+ strcat(comma_str, incbuf);
1171
+ if (trailing_comma)
1172
+ strcat(comma_str, MULTI_VALUE_SEP);
1173
+ free(incbuf);
1174
+ } while (trailing_comma);
1175
+
1176
+ return comma_str;
1177
+ }
1178
+
1179
+
1180
+ /*
1181
+ * Grab one token out of fp. Tokens are strings of non-blank
1182
+ * characters bounded by blank characters, beginning of line, and
1183
+ * end of line. Blank means space or tab. Return the token as
1184
+ * *buf. Leave file positioned at the character immediately after the
1185
+ * token or EOF, whichever comes first. If no more tokens on line,
1186
+ * return empty string as *buf and position the file to the beginning
1187
+ * of the next line or EOF, whichever comes first. Allow spaces in
1188
+ * quoted strings. Terminate on unquoted commas. Handle
1189
+ * comments. Treat unquoted keywords that might be user names or
1190
+ * database names specially, by appending a newline to them.
1191
+ */
1192
+ static void next_token(FILE *fp, char *buf, int bufsz)
1193
+ {
1194
+ int c;
1195
+ char *start_buf = buf;
1196
+ char *end_buf = buf + (bufsz - 2);
1197
+ bool in_quote = false;
1198
+ bool was_quote = false;
1199
+ bool saw_quote = false;
1200
+
1201
+ /*Assert(end_buf > start_buf);*/
1202
+
1203
+ /* Move over initial whitespace and commas */
1204
+ while ((c = getc(fp)) != EOF && (pg_isblank(c) || c == ','))
1205
+ ;
1206
+
1207
+ if (c == EOF || c == '\n')
1208
+ {
1209
+ *buf = '\0';
1210
+ return;
1211
+ }
1212
+
1213
+ /*
1214
+ * Build a token in buf of next characters up to EOF, EOL, unquoted
1215
+ * comma, or unquoted whitespace.
1216
+ */
1217
+ while (c != EOF && c != '\n' &&
1218
+ (!pg_isblank(c) || in_quote == true))
1219
+ {
1220
+ /* skip comments to EOL */
1221
+ if (c == '#' && !in_quote)
1222
+ {
1223
+ while ((c = getc(fp)) != EOF && c != '\n')
1224
+ ;
1225
+ /* If only comment, consume EOL too; return EOL */
1226
+ if (c != EOF && buf == start_buf)
1227
+ c = getc(fp);
1228
+ break;
1229
+ }
1230
+
1231
+ if (buf >= end_buf)
1232
+ {
1233
+ *buf = '\0';
1234
+ pool_log("authentication file token too long, skipping: \"%s\"", start_buf);
1235
+ /* Discard remainder of line */
1236
+ while ((c = getc(fp)) != EOF && c != '\n')
1237
+ ;
1238
+ break;
1239
+ }
1240
+
1241
+ if (c != '"' || (c == '"' && was_quote))
1242
+ *buf++ = c;
1243
+
1244
+ /* We pass back the comma so the caller knows there is more */
1245
+ if ((pg_isblank(c) || c == ',') && !in_quote)
1246
+ break;
1247
+
1248
+ /* Literal double-quote is two double-quotes */
1249
+ if (in_quote && c == '"')
1250
+ was_quote = !was_quote;
1251
+ else
1252
+ was_quote = false;
1253
+
1254
+ if (c == '"')
1255
+ {
1256
+ in_quote = !in_quote;
1257
+ saw_quote = true;
1258
+ }
1259
+
1260
+ c = getc(fp);
1261
+ }
1262
+
1263
+ /*
1264
+ * Put back the char right after the token (critical in case it is
1265
+ * EOL, since we need to detect end-of-line at next call).
1266
+ */
1267
+ if (c != EOF)
1268
+ ungetc(c, fp);
1269
+
1270
+ *buf = '\0';
1271
+
1272
+ if (!saw_quote &&
1273
+ (strcmp(start_buf, "all") == 0 ||
1274
+ strcmp(start_buf, "sameuser") == 0 ||
1275
+ strcmp(start_buf, "samegroup") == 0))
1276
+ {
1277
+ /* append newline to a magical keyword */
1278
+ *buf++ = '\n';
1279
+ *buf = '\0';
1280
+ }
1281
+ }
1282
+
1283
+
1284
+ /*
1285
+ * free memory used by lines and tokens built by tokenize_file()
1286
+ */
1287
+ static void free_lines(List **lines, List **line_nums)
1288
+ {
1289
+ if (*lines)
1290
+ {
1291
+ ListCell *line;
1292
+
1293
+ foreach(line, *lines)
1294
+ {
1295
+ List *ln = lfirst(line);
1296
+ ListCell *token;
1297
+
1298
+ foreach(token, ln)
1299
+ free(lfirst(token));
1300
+
1301
+ list_free(ln);
1302
+ }
1303
+
1304
+ list_free(*lines);
1305
+ *lines = NIL;
1306
+ }
1307
+
1308
+ if (*line_nums)
1309
+ {
1310
+ list_free(*line_nums);
1311
+ *line_nums = NIL;
1312
+ }
1313
+ }
1314
+
1315
+
1316
+ #ifdef USE_PAM
1317
+
1318
+ /*
1319
+ * PAM conversation function
1320
+ */
1321
+ static int pam_passwd_conv_proc(int num_msg, const struct pam_message ** msg,
1322
+ struct pam_response ** resp, void *appdata_ptr)
1323
+ {
1324
+ if (num_msg != 1 || msg[0]->msg_style != PAM_PROMPT_ECHO_OFF)
1325
+ {
1326
+ switch (msg[0]->msg_style)
1327
+ {
1328
+ case PAM_ERROR_MSG:
1329
+ pool_log("error from underlying PAM layer: %s",
1330
+ msg[0]->msg);
1331
+ return PAM_CONV_ERR;
1332
+ default:
1333
+ pool_log("unsupported PAM conversation %d/%s",
1334
+ msg[0]->msg_style, msg[0]->msg);
1335
+ return PAM_CONV_ERR;
1336
+ }
1337
+ }
1338
+
1339
+ if (!appdata_ptr)
1340
+ {
1341
+ /*
1342
+ * Workaround for Solaris 2.6 where the PAM library is broken and
1343
+ * does not pass appdata_ptr to the conversation routine
1344
+ */
1345
+ appdata_ptr = pam_passwd;
1346
+ }
1347
+
1348
+ /*
1349
+ * Password wasn't passed to PAM the first time around - let's go ask
1350
+ * the client to send a password, which we then stuff into PAM.
1351
+ */
1352
+ if (strlen(appdata_ptr) == 0)
1353
+ {
1354
+ char *passwd;
1355
+
1356
+ sendAuthRequest(pam_frontend_kludge, AUTH_REQ_PASSWORD);
1357
+ passwd = recv_password_packet(pam_frontend_kludge);
1358
+
1359
+ if (passwd == NULL)
1360
+ return PAM_CONV_ERR; /* client didn't want to send password */
1361
+
1362
+ if (strlen(passwd) == 0)
1363
+ {
1364
+ pool_log("empty password returned by client");
1365
+ return PAM_CONV_ERR;
1366
+ }
1367
+ appdata_ptr = passwd;
1368
+ }
1369
+
1370
+ /*
1371
+ * PAM will free this memory in * pam_end()
1372
+ */
1373
+ *resp = calloc(num_msg, sizeof(struct pam_response));
1374
+ if (!*resp)
1375
+ {
1376
+ /* originally, it was logged as LOG */
1377
+ pool_error("pam_passwd_conv_proc: calloc failed: %s", strerror(errno));
1378
+ return PAM_CONV_ERR;
1379
+ }
1380
+
1381
+ (*resp)[0].resp = strdup((char *) appdata_ptr);
1382
+ if ((*resp)[0].resp == NULL)
1383
+ {
1384
+ pool_error("pam_passwd_conv_proc: strdup failed: %s", strerror(errno));
1385
+ exit(1);
1386
+ }
1387
+ (*resp)[0].resp_retcode = 0;
1388
+
1389
+ return ((*resp)[0].resp ? PAM_SUCCESS : PAM_CONV_ERR);
1390
+ }
1391
+
1392
+
1393
+ /*
1394
+ * Check authentication against PAM.
1395
+ */
1396
+ static POOL_STATUS CheckPAMAuth(POOL_CONNECTION *frontend, char *user, char *password)
1397
+ {
1398
+ int retval;
1399
+ pam_handle_t *pamh = NULL;
1400
+
1401
+ /*
1402
+ * Apparently, Solaris 2.6 is broken, and needs ugly static variable
1403
+ * workaround
1404
+ */
1405
+ pam_passwd = password;
1406
+
1407
+ /*
1408
+ * Set the application data portion of the conversation struct This is
1409
+ * later used inside the PAM conversation to pass the password to the
1410
+ * authentication module.
1411
+ */
1412
+ pam_passw_conv.appdata_ptr = (char *) password; /* from password above,
1413
+ * not allocated */
1414
+
1415
+ /* Optionally, one can set the service name in pool_hba.conf */
1416
+ if (frontend->auth_arg && frontend->auth_arg[0] != '\0')
1417
+ retval = pam_start(frontend->auth_arg, "pgpool@",
1418
+ &pam_passw_conv, &pamh);
1419
+ else
1420
+ retval = pam_start(PGPOOL_PAM_SERVICE, "pgpool@",
1421
+ &pam_passw_conv, &pamh);
1422
+
1423
+ if (retval != PAM_SUCCESS)
1424
+ {
1425
+ pool_log("could not create PAM authenticator: %s",
1426
+ pam_strerror(pamh, retval));
1427
+ pam_passwd = NULL; /* Unset pam_passwd */
1428
+ return POOL_ERROR;
1429
+ }
1430
+
1431
+ retval = pam_set_item(pamh, PAM_USER, user);
1432
+ if (retval != PAM_SUCCESS)
1433
+ {
1434
+ pool_log("pam_set_item(PAM_USER) failed: %s",
1435
+ pam_strerror(pamh, retval));
1436
+ pam_passwd = NULL; /* Unset pam_passwd */
1437
+ return POOL_ERROR;
1438
+ }
1439
+
1440
+ retval = pam_set_item(pamh, PAM_CONV, &pam_passw_conv);
1441
+ if (retval != PAM_SUCCESS)
1442
+ {
1443
+ pool_log("pam_set_item(PAM_CONV) failed: %s",
1444
+ pam_strerror(pamh, retval));
1445
+ pam_passwd = NULL; /* Unset pam_passwd */
1446
+ return POOL_ERROR;
1447
+ }
1448
+
1449
+ retval = pam_authenticate(pamh, 0);
1450
+ if (retval != PAM_SUCCESS) /* service name does not exist */
1451
+ {
1452
+ pool_log("pam_authenticate failed: %s",
1453
+ pam_strerror(pamh, retval));
1454
+ pam_passwd = NULL; /* Unset pam_passwd */
1455
+ return POOL_ERROR;
1456
+ }
1457
+
1458
+ retval = pam_acct_mgmt(pamh, 0);
1459
+ if (retval != PAM_SUCCESS)
1460
+ {
1461
+ pool_log("pam_acct_mgmt failed: %s",
1462
+ pam_strerror(pamh, retval));
1463
+ pam_passwd = NULL; /* Unset pam_passwd */
1464
+ return POOL_ERROR;
1465
+ }
1466
+
1467
+ retval = pam_end(pamh, retval);
1468
+ if (retval != PAM_SUCCESS)
1469
+ {
1470
+ pool_log("could not release PAM authenticator: %s",
1471
+ pam_strerror(pamh, retval));
1472
+ }
1473
+
1474
+ pam_passwd = NULL; /* Unset pam_passwd */
1475
+
1476
+ return (retval == PAM_SUCCESS ? POOL_CONTINUE : POOL_ERROR);
1477
+ }
1478
+
1479
+ #endif /* USE_PAM */
1480
+
1481
+ static POOL_STATUS CheckMd5Auth(char *username)
1482
+ {
1483
+ char *passwd;
1484
+
1485
+ /* Look for the entry in pool_passwd */
1486
+ passwd = pool_get_passwd(username);
1487
+
1488
+ if (passwd == NULL)
1489
+ {
1490
+ /* Not found. authentication failed */
1491
+ return POOL_ERROR;
1492
+ }
1493
+
1494
+ /*
1495
+ * Ok for now. Actual authentication will be performed later.
1496
+ */
1497
+ return POOL_CONTINUE;
1498
+ }
1499
+
1500
+ static bool prestogres_hba_set_session_info(const char* key, const char* value)
1501
+ {
1502
+ pool_debug("presto_external_auth_prog: key:%s value:%s", key, value);
1503
+
1504
+ if (strcmp(key, "server") == 0) {
1505
+ presto_server = value;
1506
+ return true;
1507
+ } else if (strcmp(key, "user") == 0) {
1508
+ presto_user = value;
1509
+ return true;
1510
+ } else if (strcmp(key, "catalog") == 0) {
1511
+ presto_catalog = value;
1512
+ return true;
1513
+ } else if (strcmp(key, "schema") == 0) {
1514
+ presto_schema = value;
1515
+ return true;
1516
+ } else if (strcmp(key, "auth_prog") == 0) {
1517
+ presto_external_auth_prog = value;
1518
+ return true;
1519
+ }
1520
+
1521
+ pool_log("prestogres_hba_set_session_info: found unknown pool_hba config argument '%s'", key);
1522
+ return false;
1523
+ }
1524
+
1525
+ static void prestogres_hba_parse_arg(const char* arg)
1526
+ {
1527
+ char *str, *tok;
1528
+
1529
+ if (arg == NULL) {
1530
+ return;
1531
+ }
1532
+
1533
+ str = strdup(arg);
1534
+ for (tok = strtok(str, MULTI_VALUE_SEP "\n");
1535
+ tok != NULL; tok = strtok(NULL, MULTI_VALUE_SEP "\n"))
1536
+ {
1537
+ char* p = strchr(tok, ':');
1538
+ if (p == NULL) {
1539
+ break;
1540
+ }
1541
+ *p = '\0';
1542
+ prestogres_hba_set_session_info(tok, p + 1);
1543
+ }
1544
+ }
1545
+
1546
+ static POOL_STATUS pool_prestogres_hba_auth_md5(POOL_CONNECTION *frontend)
1547
+ {
1548
+ char *pool_passwd = NULL;
1549
+ static int size;
1550
+ static char password[MAX_PASSWORD_SIZE];
1551
+ static char encbuf[POOL_PASSWD_LEN+1];
1552
+ char salt[4];
1553
+
1554
+ prestogres_hba_parse_arg(frontend->auth_arg);
1555
+
1556
+ pool_passwd = pool_get_passwd(frontend->username);
1557
+ pool_random_salt(salt);
1558
+
1559
+ if (send_md5auth_request(frontend, frontend->protoVersion, salt))
1560
+ {
1561
+ pool_error("pool_prestogres_hba_auth_md5: send_md5auth_request failed");
1562
+ return POOL_ERROR;
1563
+ }
1564
+
1565
+ /* Read password packet */
1566
+ if (read_password_packet(frontend, frontend->protoVersion, password, &size))
1567
+ {
1568
+ pool_debug("pool_prestogres_hba_auth_md5: read_password_packet failed");
1569
+ return POOL_ERROR;
1570
+ }
1571
+
1572
+ pg_md5_encrypt(pool_passwd+strlen("md5"), salt, sizeof(salt), encbuf);
1573
+ if (strcmp(password, encbuf))
1574
+ {
1575
+ /* Password does not match */
1576
+ pool_debug("password does not match: frontend:%s pgpool:%s", password, encbuf);
1577
+ return POOL_ERROR;
1578
+ }
1579
+
1580
+ return POOL_CONTINUE;
1581
+ }
1582
+
1583
+ static bool do_external_auth(POOL_CONNECTION* frontend, const char* password)
1584
+ {
1585
+ pid_t pid;
1586
+ int status;
1587
+
1588
+ int stdin_pair[2];
1589
+ int stdout_pair[2];
1590
+ FILE* stdin_writer;
1591
+ FILE* stdout_reader;
1592
+
1593
+ char hostinfo[NI_MAXHOST];
1594
+ char buffer[10*1024];
1595
+ char *pos, *line;
1596
+
1597
+ if (pipe(stdin_pair) < 0) {
1598
+ pool_error("pipe() failed. reason: %s", strerror(errno));
1599
+ exit(1);
1600
+ }
1601
+ if (pipe(stdout_pair) < 0) {
1602
+ pool_error("pipe() failed. reason: %s", strerror(errno));
1603
+ exit(1);
1604
+ }
1605
+
1606
+ pid = fork();
1607
+ if (pid == 0) {
1608
+ close(stdin_pair[1]);
1609
+ close(stdout_pair[0]);
1610
+ if (dup2(stdin_pair[0], 0) < 0) {
1611
+ exit(127);
1612
+ }
1613
+ if (dup2(stdout_pair[1], 1) < 0) {
1614
+ exit(127);
1615
+ }
1616
+ execlp(presto_external_auth_prog, presto_external_auth_prog, NULL);
1617
+ exit(127);
1618
+ } else if (pid == -1) {
1619
+ pool_error("fork() failed. reason: %s", strerror(errno));
1620
+ exit(1);
1621
+ }
1622
+
1623
+ close(stdin_pair[0]);
1624
+ close(stdout_pair[1]);
1625
+
1626
+ stdin_writer = fdopen(stdin_pair[1], "w");
1627
+ if (stdin_writer == NULL) {
1628
+ pool_error("fdopen() failed. reason: %s", strerror(errno));
1629
+ exit(1);
1630
+ }
1631
+
1632
+ stdout_reader = fdopen(stdout_pair[0], "r");
1633
+ if (stdout_pair == NULL) {
1634
+ pool_error("fdopen() failed. reason: %s", strerror(errno));
1635
+ exit(1);
1636
+ }
1637
+
1638
+ fprintf(stdin_writer, "user:%s\n", frontend->username);
1639
+ fprintf(stdin_writer, "password:%s\n", password);
1640
+ fprintf(stdin_writer, "database:%s\n", frontend->database);
1641
+ getnameinfo_all(&frontend->raddr.addr, sizeof(frontend->raddr.addr),
1642
+ hostinfo, sizeof(hostinfo), NULL, 0, NI_NUMERICHOST);
1643
+ fprintf(stdin_writer, "address:%s\n", hostinfo);
1644
+ fprintf(stdin_writer, "\n");
1645
+ fclose(stdin_writer);
1646
+
1647
+ pos = buffer;
1648
+ while (true) {
1649
+ char* const buffer_end = buffer + sizeof(buffer);
1650
+ if (buffer_end <= pos) {
1651
+ break;
1652
+ }
1653
+
1654
+ line = fgets(pos, buffer_end - pos, stdout_reader);
1655
+ if (line == NULL || line[0] == '\n') {
1656
+ break;
1657
+ }
1658
+
1659
+ pos += strlen(line);
1660
+ }
1661
+
1662
+ prestogres_hba_parse_arg(buffer);
1663
+
1664
+ if (waitpid(pid, &status, 0) < 0) {
1665
+ pool_error("waitpid() failed. reason: %s", strerror(errno));
1666
+ exit(1);
1667
+ }
1668
+
1669
+ return WIFEXITED(status) && WEXITSTATUS(status) == 0;
1670
+ }
1671
+
1672
+ static POOL_STATUS pool_prestogres_hba_auth_external(POOL_CONNECTION *frontend)
1673
+ {
1674
+ char *passwd;
1675
+
1676
+ prestogres_hba_parse_arg(frontend->auth_arg);
1677
+
1678
+ if (presto_external_auth_prog == NULL) {
1679
+ presto_external_auth_prog = pool_config->presto_external_auth_prog;
1680
+ if (presto_external_auth_prog == NULL) {
1681
+ pool_error("pool_prestogres_hba_auth_external: 'prog:' argument is not set to pool_hba entry for user '%s'", frontend->username);
1682
+ exit(1);
1683
+ }
1684
+ }
1685
+
1686
+ sendAuthRequest(frontend, AUTH_REQ_PASSWORD);
1687
+ passwd = recv_password_packet(frontend);
1688
+
1689
+ if (passwd == NULL)
1690
+ return POOL_ERROR; /* client didn't want to send password */
1691
+
1692
+ if (strlen(passwd) == 0) {
1693
+ pool_log("empty password returned by client");
1694
+ return POOL_ERROR;
1695
+ }
1696
+
1697
+ if (!do_external_auth(frontend, passwd)) {
1698
+ return POOL_ERROR;
1699
+ }
1700
+
1701
+ return POOL_CONTINUE;
1702
+ }
1703
+
1704
+ void pool_prestogres_init_session(POOL_CONNECTION *frontend)
1705
+ {
1706
+ if (presto_server == NULL) {
1707
+ presto_server = pool_config->presto_server;
1708
+ }
1709
+ if (presto_user == NULL) {
1710
+ presto_user = frontend->username;
1711
+ }
1712
+ if (presto_catalog == NULL) {
1713
+ presto_catalog = pool_config->presto_catalog;
1714
+ }
1715
+ if (presto_schema == NULL) {
1716
+ presto_schema = pool_config->presto_schema;
1717
+ }
1718
+ pool_debug("pool_prestogres_init_session: presto_server: %s", presto_server);
1719
+ pool_debug("pool_prestogres_init_session: presto_user: %s", presto_user);
1720
+ pool_debug("pool_prestogres_init_session: presto_catalog: %s", presto_catalog);
1721
+ pool_debug("pool_prestogres_init_session: presto_schema: %s", presto_schema);
1722
+ }
1723
+