prestogres 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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
+