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