metasploit-framework/lib/msfdb_helpers/pg_ctl.rb

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

164 lines
4.7 KiB
Ruby
Raw Normal View History

2021-04-20 19:26:42 +08:00
require 'msfdb_helpers/db_interface'
2021-04-30 21:24:56 +08:00
module MsfdbHelpers
class PgCtl < DbInterface
def initialize(db_path:, options:, localconf:, db_conf:)
@db = db_path
@options = options
@localconf = localconf
@db_conf = db_conf
@socket_directory = db_path
2021-04-30 21:24:56 +08:00
super(options)
2021-04-26 09:24:11 +08:00
end
2021-04-30 21:24:56 +08:00
def init(msf_pass, msftest_pass)
puts "Creating database at #{@db}"
Dir.mkdir(@db)
2021-05-13 23:44:17 +08:00
run_cmd("initdb --auth-host=trust --auth-local=trust -E UTF8 #{@db.shellescape}")
2022-01-25 22:54:14 +08:00
2022-01-25 22:41:57 +08:00
File.open("#{@db}/postgresql.conf", 'a') do |f|
f.puts "port = #{@options[:db_port]}"
end
# Try creating a test file at {Dir.tmpdir},
# Else fallback to creation at @{db}
# Else fail with error.
if test_executable_file("#{Dir.tmpdir}")
@socket_directory = Dir.tmpdir
elsif test_executable_file("#{@db}")
@socket_directory = @db
else
2022-07-28 00:47:31 +08:00
print_error("Attempt to create DB socket file at Temporary Directory and `~/.msf4/db` failed. Possibly because they are mounted with NOEXEC flags. Database initialization failed.")
2021-04-30 21:24:56 +08:00
end
2021-04-30 21:24:56 +08:00
start
2021-04-26 09:24:11 +08:00
2021-04-30 21:24:56 +08:00
create_db_users(msf_pass, msftest_pass)
2021-04-30 21:24:56 +08:00
write_db_client_auth_config
restart
end
# Creates and attempts to execute a testfile in the specified directory,
# to determine if it is mounted with NOEXEC flags.
def test_executable_file(path)
begin
file_name = File.join(path, 'msfdb_testfile')
File.open(file_name, 'w') do |f|
f.puts "#!/bin/bash\necho exec"
end
File.chmod(0744, file_name)
if run_cmd(file_name)
File.open("#{@db}/postgresql.conf", 'a') do |f|
f.puts "unix_socket_directories = \'#{path}\'"
end
puts "Creating db socket file at #{path}"
end
return true
rescue => e
return false
ensure
begin
File.delete(file_name)
rescue
print_error("Unable to delete test file #{file_name}")
end
end
end
2021-04-30 21:24:56 +08:00
def delete
if exists?
2021-04-30 21:24:56 +08:00
stop
2021-04-30 21:24:56 +08:00
if @options[:delete_existing_data]
puts "Deleting all data at #{@db}"
FileUtils.rm_rf(@db)
end
if @options[:delete_existing_data]
FileUtils.rm_r(@db_conf, force: true)
2021-04-30 21:24:56 +08:00
end
else
puts "No data at #{@db}, doing nothing"
end
end
2021-04-30 21:24:56 +08:00
def start
if status == DatabaseStatus::RUNNING
2021-04-30 21:24:56 +08:00
puts "Database already started at #{@db}"
return true
end
print "Starting database at #{@db}..."
2021-05-13 23:44:17 +08:00
run_cmd("pg_ctl -o \"-p #{@options[:db_port]}\" -D #{@db.shellescape} -l #{@db.shellescape}/log start")
2021-04-30 21:24:56 +08:00
sleep(2)
2021-05-13 23:44:17 +08:00
if run_cmd("pg_ctl -o \"-p #{@options[:db_port]}\" -D #{@db.shellescape} status") != 0
2021-04-30 21:24:56 +08:00
puts 'failed'.red.bold.to_s
false
else
puts 'success'.green.bold.to_s
true
end
end
2021-04-30 21:24:56 +08:00
def stop
if status == DatabaseStatus::RUNNING
2021-04-30 21:24:56 +08:00
puts "Stopping database at #{@db}"
2021-05-13 23:44:17 +08:00
run_cmd("pg_ctl -o \"-p #{@options[:db_port]}\" -D #{@db.shellescape} stop")
2021-04-30 21:24:56 +08:00
else
puts "Database is no longer running at #{@db}"
end
end
2021-04-30 21:24:56 +08:00
def restart
stop
start
end
def exists?
Dir.exist?(@db)
end
2021-04-30 21:24:56 +08:00
def status
if exists?
2021-05-13 23:44:17 +08:00
if run_cmd("pg_ctl -o \"-p #{@options[:db_port]}\" -D #{@db.shellescape} status") == 0
DatabaseStatus::RUNNING
2021-04-30 21:24:56 +08:00
else
DatabaseStatus::INACTIVE
2021-04-30 21:24:56 +08:00
end
else
DatabaseStatus::NOT_FOUND
end
end
2021-04-30 21:24:56 +08:00
def create_db_users(msf_pass, msftest_pass)
puts 'Creating database users'
run_psql("create user #{@options[:msf_db_user].shellescape} with password '#{msf_pass}'", @socket_directory)
run_psql("create user #{@options[:msftest_db_user].shellescape} with password '#{msftest_pass}'", @socket_directory)
run_psql("alter role #{@options[:msf_db_user].shellescape} createdb", @socket_directory)
run_psql("alter role #{@options[:msftest_db_user].shellescape} createdb", @socket_directory)
run_psql("alter role #{@options[:msf_db_user].shellescape} with password '#{msf_pass}'", @socket_directory)
run_psql("alter role #{@options[:msftest_db_user].shellescape} with password '#{msftest_pass}'", @socket_directory)
2021-04-30 21:24:56 +08:00
conn = PG.connect(host: @options[:db_host], dbname: 'postgres', port: @options[:db_port], user: @options[:msf_db_user], password: msf_pass)
conn.exec("CREATE DATABASE #{@options[:msf_db_name]}")
conn.exec("CREATE DATABASE #{@options[:msftest_db_name]}")
conn.finish
end
2021-04-26 09:24:11 +08:00
2021-04-30 21:24:56 +08:00
def write_db_client_auth_config
client_auth_config = "#{@db}/pg_hba.conf"
super(client_auth_config)
end
2021-04-20 20:47:47 +08:00
2021-04-30 21:24:56 +08:00
def self.requirements
%w[psql pg_ctl initdb createdb]
end
2021-04-20 20:47:47 +08:00
end
end