V-72897

Severity: Medium

Generated

2019-05-20 15:48:11.984914

Status

Passed

Database objects (including but not limited to tables, indexes, storage, trigger procedures, functions, links to software external to PostgreSQL, etc.) must be owned by database/DBMS principals authorized for ownership.

NIST 800-53

STIG # Description Result
CM-5 CM-5: Access Restrictions For Change passed

Guidance

Within the database, object ownership implies full privileges to the owned object, including the privilege to assign access to the owned objects to other subjects. Database functions and procedures can be coded using definer’s rights. This allows anyone who utilizes the object to perform the actions if they were the owner. If not properly managed, this can lead to privileged actions being taken by unauthorized individuals. Conversely, if critical tables or other objects rely on unauthorized owner accounts, these objects may be lost when an account is removed.

Check

Review system documentation to identify accounts authorized to own database objects. Review accounts that own objects in the database(s). If any database objects are found to be owned by users not authorized to own database objects, this is a finding. To check the ownership of objects in the database, as the database administrator, run the following SQL: $ sudo su - postgres $ psql -x -c “\dn .“ $ psql -x -c “\dt .“ $ psql -x -c “\ds .“ $ psql -x -c “\dv .“ $ psql -x -c “\df+ .“ If any object is not owned by an authorized role for ownership, this is a finding.

Fix

Assign ownership of authorized objects to authorized object owner accounts. #### Schema Owner To create a schema owned by the user bob, run the following SQL: $ sudo su - postgres $ psql -c “CREATE SCHEMA test AUTHORIZATION bob To alter the ownership of an existing object to be owned by the user bob, run the following SQL: $ sudo su - postgres $ psql -c “ALTER SCHEMA test OWNER TO bob”

Test Results

  Result
PostgreSQL query: SELECT n.nspname, pg_catalog.pg_get_userbyid(n.nspowner) FROM pg_catalog.pg_namespace n WHERE pg_catalog.pg_get_userbyid(n.nspowner) <> 'vcap'; output should eq "" passed
PostgreSQL query: SELECT n.nspname, p.proname, pg_catalog.pg_get_userbyid(n.nspowner) FROM pg_catalog.pg_proc p LEFT JOIN pg_catalog.pg_namespace n ON n.oid = p.pronamespace WHERE pg_catalog.pg_get_userbyid(n.nspowner) <> 'vcap'; output should eq "" passed
PostgreSQL query: SELECT n.nspname, c.relname, c.relkind, pg_catalog.pg_get_userbyid(n.nspowner) FROM pg_catalog.pg_class c LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace WHERE c.relkind IN ('t','s','') AND pg_catalog.pg_get_userbyid(n.nspowner) <> 'vcap' output should eq "" passed
PostgreSQL query: SELECT n.nspname, c.relname, c.relkind, pg_catalog.pg_get_userbyid(n.nspowner) FROM pg_catalog.pg_class c LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace WHERE c.relkind IN ('s','s','') AND pg_catalog.pg_get_userbyid(n.nspowner) <> 'vcap' output should eq "" passed
PostgreSQL query: SELECT n.nspname, c.relname, c.relkind, pg_catalog.pg_get_userbyid(n.nspowner) FROM pg_catalog.pg_class c LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace WHERE c.relkind IN ('v','s','') AND pg_catalog.pg_get_userbyid(n.nspowner) <> 'vcap' output should eq "" passed
PostgreSQL query with errors: SELECT n.nspname, pg_catalog.pg_get_userbyid(n.nspowner) FROM pg_catalog.pg_namespace n WHERE pg_catalog.pg_get_userbyid(n.nspowner) NOT IN ('testuser','dashboard','replication','vcap','crunchy') AND n.nspname !~ '^pg_' AND n.nspname <> 'information_schema'; output should match /FATAL:\s+database "template0" is not currently accepting connections/ passed
PostgreSQL query with errors: SELECT n.nspname, p.proname, pg_catalog.pg_get_userbyid(n.nspowner) FROM pg_catalog.pg_proc p LEFT JOIN pg_catalog.pg_namespace n ON n.oid = p.pronamespace WHERE pg_catalog.pg_get_userbyid(n.nspowner) NOT IN ('testuser','dashboard','replication','vcap','crunchy') AND n.nspname <> 'pg_catalog' AND n.nspname <> 'information_schema'; output should match /FATAL:\s+database "template0" is not currently accepting connections/ passed
PostgreSQL query with errors: SELECT n.nspname, c.relname, c.relkind, pg_catalog.pg_get_userbyid(n.nspowner) FROM pg_catalog.pg_class c LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace WHERE c.relkind IN ('t','s','') AND pg_catalog.pg_get_userbyid(n.nspowner) NOT IN ('testuser','dashboard','replication','vcap','crunchy') AND n.nspname <> 'pg_catalog' AND n.nspname <> 'information_schema' AND n.nspname !~ '^pg_toast'; output should match /FATAL:\s+database "template0" is not currently accepting connections/ passed
PostgreSQL query with errors: SELECT n.nspname, c.relname, c.relkind, pg_catalog.pg_get_userbyid(n.nspowner) FROM pg_catalog.pg_class c LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace WHERE c.relkind IN ('s','s','') AND pg_catalog.pg_get_userbyid(n.nspowner) NOT IN ('testuser','dashboard','replication','vcap','crunchy') AND n.nspname <> 'pg_catalog' AND n.nspname <> 'information_schema' AND n.nspname !~ '^pg_toast'; output should match /FATAL:\s+database "template0" is not currently accepting connections/ passed
PostgreSQL query: SELECT n.nspname, p.proname, pg_catalog.pg_get_userbyid(n.nspowner) FROM pg_catalog.pg_proc p LEFT JOIN pg_catalog.pg_namespace n ON n.oid = p.pronamespace WHERE pg_catalog.pg_get_userbyid(n.nspowner) NOT IN ('testuser','dashboard','replication','vcap','crunchy') AND n.nspname <> 'pg_catalog' AND n.nspname <> 'information_schema'; output should eq "" passed
PostgreSQL query with errors: SELECT n.nspname, c.relname, c.relkind, pg_catalog.pg_get_userbyid(n.nspowner) FROM pg_catalog.pg_class c LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace WHERE c.relkind IN ('v','s','') AND pg_catalog.pg_get_userbyid(n.nspowner) NOT IN ('testuser','dashboard','replication','vcap','crunchy') AND n.nspname <> 'pg_catalog' AND n.nspname <> 'information_schema' AND n.nspname !~ '^pg_toast'; output should match /FATAL:\s+database "template0" is not currently accepting connections/ passed
PostgreSQL query: SELECT n.nspname, pg_catalog.pg_get_userbyid(n.nspowner) FROM pg_catalog.pg_namespace n WHERE pg_catalog.pg_get_userbyid(n.nspowner) NOT IN ('testuser','dashboard','replication','vcap','crunchy') AND n.nspname !~ '^pg_' AND n.nspname <> 'information_schema'; output should eq "" passed
PostgreSQL query: SELECT n.nspname, p.proname, pg_catalog.pg_get_userbyid(n.nspowner) FROM pg_catalog.pg_proc p LEFT JOIN pg_catalog.pg_namespace n ON n.oid = p.pronamespace WHERE pg_catalog.pg_get_userbyid(n.nspowner) NOT IN ('testuser','dashboard','replication','vcap','crunchy') AND n.nspname <> 'pg_catalog' AND n.nspname <> 'information_schema'; output should eq "" passed
PostgreSQL query: SELECT n.nspname, c.relname, c.relkind, pg_catalog.pg_get_userbyid(n.nspowner) FROM pg_catalog.pg_class c LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace WHERE c.relkind IN ('t','s','') AND pg_catalog.pg_get_userbyid(n.nspowner) NOT IN ('testuser','dashboard','replication','vcap','crunchy') AND n.nspname <> 'pg_catalog' AND n.nspname <> 'information_schema' AND n.nspname !~ '^pg_toast'; output should eq "" passed
PostgreSQL query: SELECT n.nspname, c.relname, c.relkind, pg_catalog.pg_get_userbyid(n.nspowner) FROM pg_catalog.pg_class c LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace WHERE c.relkind IN ('s','s','') AND pg_catalog.pg_get_userbyid(n.nspowner) NOT IN ('testuser','dashboard','replication','vcap','crunchy') AND n.nspname <> 'pg_catalog' AND n.nspname <> 'information_schema' AND n.nspname !~ '^pg_toast'; output should eq "" passed
PostgreSQL query: SELECT n.nspname, c.relname, c.relkind, pg_catalog.pg_get_userbyid(n.nspowner) FROM pg_catalog.pg_class c LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace WHERE c.relkind IN ('v','s','') AND pg_catalog.pg_get_userbyid(n.nspowner) NOT IN ('testuser','dashboard','replication','vcap','crunchy') AND n.nspname <> 'pg_catalog' AND n.nspname <> 'information_schema' AND n.nspname !~ '^pg_toast'; output should eq "" passed
PostgreSQL query: SELECT n.nspname, pg_catalog.pg_get_userbyid(n.nspowner) FROM pg_catalog.pg_namespace n WHERE pg_catalog.pg_get_userbyid(n.nspowner) NOT IN ('testuser','dashboard','replication','vcap','crunchy') AND n.nspname !~ '^pg_' AND n.nspname <> 'information_schema'; output should eq "" passed
PostgreSQL query: SELECT n.nspname, p.proname, pg_catalog.pg_get_userbyid(n.nspowner) FROM pg_catalog.pg_proc p LEFT JOIN pg_catalog.pg_namespace n ON n.oid = p.pronamespace WHERE pg_catalog.pg_get_userbyid(n.nspowner) NOT IN ('testuser','dashboard','replication','vcap','crunchy') AND n.nspname <> 'pg_catalog' AND n.nspname <> 'information_schema'; output should eq "" passed
PostgreSQL query: SELECT n.nspname, c.relname, c.relkind, pg_catalog.pg_get_userbyid(n.nspowner) FROM pg_catalog.pg_class c LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace WHERE c.relkind IN ('t','s','') AND pg_catalog.pg_get_userbyid(n.nspowner) NOT IN ('testuser','dashboard','replication','vcap','crunchy') AND n.nspname <> 'pg_catalog' AND n.nspname <> 'information_schema' AND n.nspname !~ '^pg_toast'; output should eq "" passed
PostgreSQL query: SELECT n.nspname, c.relname, c.relkind, pg_catalog.pg_get_userbyid(n.nspowner) FROM pg_catalog.pg_class c LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace WHERE c.relkind IN ('s','s','') AND pg_catalog.pg_get_userbyid(n.nspowner) NOT IN ('testuser','dashboard','replication','vcap','crunchy') AND n.nspname <> 'pg_catalog' AND n.nspname <> 'information_schema' AND n.nspname !~ '^pg_toast'; output should eq "" passed
PostgreSQL query: SELECT n.nspname, c.relname, c.relkind, pg_catalog.pg_get_userbyid(n.nspowner) FROM pg_catalog.pg_class c LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace WHERE c.relkind IN ('v','s','') AND pg_catalog.pg_get_userbyid(n.nspowner) NOT IN ('testuser','dashboard','replication','vcap','crunchy') AND n.nspname <> 'pg_catalog' AND n.nspname <> 'information_schema' AND n.nspname !~ '^pg_toast'; output should eq "" passed
PostgreSQL query: SELECT n.nspname, pg_catalog.pg_get_userbyid(n.nspowner) FROM pg_catalog.pg_namespace n WHERE pg_catalog.pg_get_userbyid(n.nspowner) NOT IN ('testuser','dashboard','replication','vcap','crunchy') AND n.nspname !~ '^pg_' AND n.nspname <> 'information_schema'; output should eq "" passed
PostgreSQL query: SELECT n.nspname, p.proname, pg_catalog.pg_get_userbyid(n.nspowner) FROM pg_catalog.pg_proc p LEFT JOIN pg_catalog.pg_namespace n ON n.oid = p.pronamespace WHERE pg_catalog.pg_get_userbyid(n.nspowner) NOT IN ('testuser','dashboard','replication','vcap','crunchy') AND n.nspname <> 'pg_catalog' AND n.nspname <> 'information_schema'; output should eq "" passed
PostgreSQL query: SELECT n.nspname, c.relname, c.relkind, pg_catalog.pg_get_userbyid(n.nspowner) FROM pg_catalog.pg_class c LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace WHERE c.relkind IN ('t','s','') AND pg_catalog.pg_get_userbyid(n.nspowner) NOT IN ('testuser','dashboard','replication','vcap','crunchy') AND n.nspname <> 'pg_catalog' AND n.nspname <> 'information_schema' AND n.nspname !~ '^pg_toast'; output should eq "" passed
PostgreSQL query: SELECT n.nspname, c.relname, c.relkind, pg_catalog.pg_get_userbyid(n.nspowner) FROM pg_catalog.pg_class c LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace WHERE c.relkind IN ('s','s','') AND pg_catalog.pg_get_userbyid(n.nspowner) NOT IN ('testuser','dashboard','replication','vcap','crunchy') AND n.nspname <> 'pg_catalog' AND n.nspname <> 'information_schema' AND n.nspname !~ '^pg_toast'; output should eq "" passed
PostgreSQL query: SELECT n.nspname, c.relname, c.relkind, pg_catalog.pg_get_userbyid(n.nspowner) FROM pg_catalog.pg_class c LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace WHERE c.relkind IN ('v','s','') AND pg_catalog.pg_get_userbyid(n.nspowner) NOT IN ('testuser','dashboard','replication','vcap','crunchy') AND n.nspname <> 'pg_catalog' AND n.nspname <> 'information_schema' AND n.nspname !~ '^pg_toast'; output should eq "" passed
PostgreSQL query: SELECT n.nspname, pg_catalog.pg_get_userbyid(n.nspowner) FROM pg_catalog.pg_namespace n WHERE pg_catalog.pg_get_userbyid(n.nspowner) NOT IN ('testuser','dashboard','replication','vcap','crunchy') AND n.nspname !~ '^pg_' AND n.nspname <> 'information_schema'; output should eq "" passed
PostgreSQL query: SELECT n.nspname, c.relname, c.relkind, pg_catalog.pg_get_userbyid(n.nspowner) FROM pg_catalog.pg_class c LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace WHERE c.relkind IN ('t','s','') AND pg_catalog.pg_get_userbyid(n.nspowner) NOT IN ('testuser','dashboard','replication','vcap','crunchy') AND n.nspname <> 'pg_catalog' AND n.nspname <> 'information_schema' AND n.nspname !~ '^pg_toast'; output should eq "" passed
PostgreSQL query: SELECT n.nspname, c.relname, c.relkind, pg_catalog.pg_get_userbyid(n.nspowner) FROM pg_catalog.pg_class c LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace WHERE c.relkind IN ('s','s','') AND pg_catalog.pg_get_userbyid(n.nspowner) NOT IN ('testuser','dashboard','replication','vcap','crunchy') AND n.nspname <> 'pg_catalog' AND n.nspname <> 'information_schema' AND n.nspname !~ '^pg_toast'; output should eq "" passed
PostgreSQL query: SELECT n.nspname, c.relname, c.relkind, pg_catalog.pg_get_userbyid(n.nspowner) FROM pg_catalog.pg_class c LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace WHERE c.relkind IN ('v','s','') AND pg_catalog.pg_get_userbyid(n.nspowner) NOT IN ('testuser','dashboard','replication','vcap','crunchy') AND n.nspname <> 'pg_catalog' AND n.nspname <> 'information_schema' AND n.nspname !~ '^pg_toast'; output should eq "" passed
PostgreSQL query: SELECT n.nspname, pg_catalog.pg_get_userbyid(n.nspowner) FROM pg_catalog.pg_namespace n WHERE pg_catalog.pg_get_userbyid(n.nspowner) NOT IN ('testuser','dashboard','replication','vcap','crunchy') AND n.nspname !~ '^pg_' AND n.nspname <> 'information_schema'; output should eq "" passed
PostgreSQL query: SELECT n.nspname, p.proname, pg_catalog.pg_get_userbyid(n.nspowner) FROM pg_catalog.pg_proc p LEFT JOIN pg_catalog.pg_namespace n ON n.oid = p.pronamespace WHERE pg_catalog.pg_get_userbyid(n.nspowner) NOT IN ('testuser','dashboard','replication','vcap','crunchy') AND n.nspname <> 'pg_catalog' AND n.nspname <> 'information_schema'; output should eq "" passed
PostgreSQL query: SELECT n.nspname, c.relname, c.relkind, pg_catalog.pg_get_userbyid(n.nspowner) FROM pg_catalog.pg_class c LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace WHERE c.relkind IN ('t','s','') AND pg_catalog.pg_get_userbyid(n.nspowner) NOT IN ('testuser','dashboard','replication','vcap','crunchy') AND n.nspname <> 'pg_catalog' AND n.nspname <> 'information_schema' AND n.nspname !~ '^pg_toast'; output should eq "" passed
PostgreSQL query: SELECT n.nspname, c.relname, c.relkind, pg_catalog.pg_get_userbyid(n.nspowner) FROM pg_catalog.pg_class c LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace WHERE c.relkind IN ('s','s','') AND pg_catalog.pg_get_userbyid(n.nspowner) NOT IN ('testuser','dashboard','replication','vcap','crunchy') AND n.nspname <> 'pg_catalog' AND n.nspname <> 'information_schema' AND n.nspname !~ '^pg_toast'; output should eq "" passed
PostgreSQL query: SELECT n.nspname, c.relname, c.relkind, pg_catalog.pg_get_userbyid(n.nspowner) FROM pg_catalog.pg_class c LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace WHERE c.relkind IN ('v','s','') AND pg_catalog.pg_get_userbyid(n.nspowner) NOT IN ('testuser','dashboard','replication','vcap','crunchy') AND n.nspname <> 'pg_catalog' AND n.nspname <> 'information_schema' AND n.nspname !~ '^pg_toast'; output should eq "" passed
PostgreSQL query: SELECT n.nspname, pg_catalog.pg_get_userbyid(n.nspowner) FROM pg_catalog.pg_namespace n WHERE pg_catalog.pg_get_userbyid(n.nspowner) NOT IN ('testuser','dashboard','replication','vcap','crunchy') AND n.nspname !~ '^pg_' AND n.nspname <> 'information_schema'; output should eq "" passed
PostgreSQL query: SELECT n.nspname, p.proname, pg_catalog.pg_get_userbyid(n.nspowner) FROM pg_catalog.pg_proc p LEFT JOIN pg_catalog.pg_namespace n ON n.oid = p.pronamespace WHERE pg_catalog.pg_get_userbyid(n.nspowner) NOT IN ('testuser','dashboard','replication','vcap','crunchy') AND n.nspname <> 'pg_catalog' AND n.nspname <> 'information_schema'; output should eq "" passed
PostgreSQL query: SELECT n.nspname, c.relname, c.relkind, pg_catalog.pg_get_userbyid(n.nspowner) FROM pg_catalog.pg_class c LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace WHERE c.relkind IN ('t','s','') AND pg_catalog.pg_get_userbyid(n.nspowner) NOT IN ('testuser','dashboard','replication','vcap','crunchy') AND n.nspname <> 'pg_catalog' AND n.nspname <> 'information_schema' AND n.nspname !~ '^pg_toast'; output should eq "" passed
PostgreSQL query: SELECT n.nspname, c.relname, c.relkind, pg_catalog.pg_get_userbyid(n.nspowner) FROM pg_catalog.pg_class c LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace WHERE c.relkind IN ('s','s','') AND pg_catalog.pg_get_userbyid(n.nspowner) NOT IN ('testuser','dashboard','replication','vcap','crunchy') AND n.nspname <> 'pg_catalog' AND n.nspname <> 'information_schema' AND n.nspname !~ '^pg_toast'; output should eq "" passed
PostgreSQL query: SELECT n.nspname, c.relname, c.relkind, pg_catalog.pg_get_userbyid(n.nspowner) FROM pg_catalog.pg_class c LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace WHERE c.relkind IN ('v','s','') AND pg_catalog.pg_get_userbyid(n.nspowner) NOT IN ('testuser','dashboard','replication','vcap','crunchy') AND n.nspname <> 'pg_catalog' AND n.nspname <> 'information_schema' AND n.nspname !~ '^pg_toast'; output should eq "" passed

Code

control "V-72897" do
  title "Database objects (including but not limited to tables, indexes,
  storage, trigger procedures, functions, links to software external to
  PostgreSQL, etc.) must be owned by database/DBMS principals authorized for
  ownership."
  desc  "Within the database, object ownership implies full privileges to the
  owned object, including the privilege to assign access to the owned objects
  to other subjects. Database functions and procedures can be coded using
  definer's rights. This allows anyone who utilizes the object to perform the
  actions if they were the owner. If not properly managed, this can lead to
  privileged actions being taken by unauthorized individuals.
  Conversely, if critical tables or other objects rely on unauthorized owner
  accounts, these objects may be lost when an account is removed."
  impact 0.5
  tag "severity": "medium"
  tag "gtitle": "SRG-APP-000133-DB-000200"
  tag "gid": "V-72897"
  tag "rid": "SV-87549r1_rule"
  tag "stig_id": "PGS9-00-003100"
  tag "cci": "CCI-001499"
  tag "nist": ["CM-5 (6)", "Rev_4"]
  tag "check": "Review system documentation to identify accounts authorized to
  own database objects. Review accounts that own objects in the database(s).
  If any database objects are found to be owned by users not authorized to own
  database objects, this is a finding.
  To check the ownership of objects in the database, as the database
  administrator, run the following SQL:
  $ sudo su - postgres
  $ psql -x -c \"\\dn *.*\"
  $ psql -x -c \"\\dt *.*\"
  $ psql -x -c \"\\ds *.*\"
  $ psql -x -c \"\\dv *.*\"
  $ psql -x -c \"\\df+ *.*\"
  If any object is not owned by an authorized role for ownership, this is a
  finding."
  tag "fix": "Assign ownership of authorized objects to authorized object owner
  accounts.
  #### Schema Owner
  To create a schema owned by the user bob, run the following SQL:
  $ sudo su - postgres
  $ psql -c \"CREATE SCHEMA test AUTHORIZATION bob
  To alter the ownership of an existing object to be owned by the user bob,
  run the following SQL:
  $ sudo su - postgres
  $ psql -c \"ALTER SCHEMA test OWNER TO bob\""

  sql = postgres_session(PG_DBA, PG_DBA_PASSWORD, PG_HOST)

  binding_users = []
  if not PG_BINDINGS_DB.empty? and not PG_BINDING_USERS_SQL.empty?
    binding_users_query = sql.query(PG_BINDING_USERS_SQL, [PG_BINDINGS_DB])
    binding_users = binding_users_query.lines
  end

  authorized_owners = PG_OBJECT_OWNERS + binding_users

  databases_sql = 'SELECT datname FROM pg_catalog.pg_database;'
  databases_query = sql.query(databases_sql, [PG_DB])
  databases = databases_query.lines
  types = %w(t s v) # tables, sequences views

  databases.each do |database|
    schemas_sql = ''
    functions_sql = ''

    if database == 'postgres'
      schemas_sql = "SELECT n.nspname, pg_catalog.pg_get_userbyid(n.nspowner) "\
        "FROM pg_catalog.pg_namespace n "\
        "WHERE pg_catalog.pg_get_userbyid(n.nspowner) <> '#{PG_OWNER}';"
      functions_sql = "SELECT n.nspname, p.proname, "\
        "pg_catalog.pg_get_userbyid(n.nspowner) "\
        "FROM pg_catalog.pg_proc p "\
        "LEFT JOIN pg_catalog.pg_namespace n ON n.oid = p.pronamespace "\
        "WHERE pg_catalog.pg_get_userbyid(n.nspowner) <> '#{PG_OWNER}';"
    else
      schemas_sql = "SELECT n.nspname, pg_catalog.pg_get_userbyid(n.nspowner) "\
        "FROM pg_catalog.pg_namespace n "\
        "WHERE pg_catalog.pg_get_userbyid(n.nspowner) "\
        "NOT IN (#{authorized_owners.map { |e| "'#{e}'" }.join(',')}) "\
        "AND n.nspname !~ '^pg_' AND n.nspname <> 'information_schema';"
      functions_sql = "SELECT n.nspname, p.proname, "\
        "pg_catalog.pg_get_userbyid(n.nspowner) "\
        "FROM pg_catalog.pg_proc p "\
        "LEFT JOIN pg_catalog.pg_namespace n ON n.oid = p.pronamespace "\
        "WHERE pg_catalog.pg_get_userbyid(n.nspowner) "\
        "NOT IN (#{authorized_owners.map { |e| "'#{e}'" }.join(',')}) "\
        "AND n.nspname <> 'pg_catalog' AND n.nspname <> 'information_schema';"
    end

    connection_error = "FATAL:\\s+database \"#{database}\" is not currently "\
      "accepting connections"
    connection_error_regex = Regexp.new(connection_error)

    describe.one do
      describe sql.query(schemas_sql, [database]) do
        its('output') { should eq '' }
      end

      describe sql.query(schemas_sql, [database]) do
        it { should match connection_error_regex }
      end
    end

    describe.one do
      describe sql.query(functions_sql, [database]) do
        its('output') { should eq '' }
      end

      describe sql.query(functions_sql, [database]) do
        it { should match connection_error_regex }
      end
    end

    types.each do |type|
      objects_sql = ''

      if database == 'postgres'
        objects_sql = "SELECT n.nspname, c.relname, c.relkind, "\
          "pg_catalog.pg_get_userbyid(n.nspowner) FROM pg_catalog.pg_class c "\
          "LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace "\
          "WHERE c.relkind IN ('#{type}','s','') "\
          "AND pg_catalog.pg_get_userbyid(n.nspowner) <> '#{PG_OWNER}' "
          "AND n.nspname !~ '^pg_toast';"
      else
        objects_sql = "SELECT n.nspname, c.relname, c.relkind, "\
          "pg_catalog.pg_get_userbyid(n.nspowner) FROM pg_catalog.pg_class c "\
          "LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace "\
          "WHERE c.relkind IN ('#{type}','s','') "\
          "AND pg_catalog.pg_get_userbyid(n.nspowner) "\
          "NOT IN (#{authorized_owners.map { |e| "'#{e}'" }.join(',')}) "\
          "AND n.nspname <> 'pg_catalog' AND n.nspname <> 'information_schema'"\
          " AND n.nspname !~ '^pg_toast';"
      end

      describe.one do
        describe sql.query(objects_sql, [database]) do
          its('output') { should eq '' }
        end

        describe sql.query(objects_sql, [database]) do
          it { should match connection_error_regex }
        end
      end
    end
  end
end