Skip to content

Fix incorrectly quoted GRANT cmd on functions #1150

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Mar 16, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 22 additions & 6 deletions manifests/server/grant.pp
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,13 @@
case $ensure {
default: {
# default is 'present'
$sql_command = 'GRANT %s ON %s "%s"%s TO "%s"'
$sql_command = 'GRANT %s ON %s "%s%s" TO "%s"'
$sql_command_unquoted = 'GRANT %s ON %s %s%s TO "%s"'
$unless_is = true
}
'absent': {
$sql_command = 'REVOKE %s ON %s "%s"%s FROM "%s"'
$sql_command = 'REVOKE %s ON %s "%s%s" FROM "%s"'
$sql_command_unquoted = 'REVOKE %s ON %s %s%s FROM "%s"'
$unless_is = false
}
}
Expand Down Expand Up @@ -115,6 +117,7 @@
'absent' => 'role_exists',
}
$arguments = ''
$_enquote_object = true
}
'SCHEMA': {
$unless_privilege = $_privilege ? {
Expand All @@ -131,6 +134,7 @@
$on_db = $db
$onlyif_function = undef
$arguments = ''
$_enquote_object = true
}
'SEQUENCE': {
$unless_privilege = $_privilege ? {
Expand All @@ -148,6 +152,7 @@
$on_db = $db
$onlyif_function = undef
$arguments = ''
$_enquote_object = true
}
'ALL SEQUENCES IN SCHEMA': {
case $_privilege {
Expand All @@ -165,6 +170,7 @@
$on_db = $db
$onlyif_function = undef
$arguments = ''
$_enquote_object = true

$schema = $object_name

Expand Down Expand Up @@ -282,6 +288,7 @@
default => undef,
}
$arguments = ''
$_enquote_object = true
}
'ALL TABLES IN SCHEMA': {
case $_privilege {
Expand All @@ -303,6 +310,7 @@
$on_db = $db
$onlyif_function = undef
$arguments = ''
$_enquote_object = true

$schema = $object_name

Expand Down Expand Up @@ -375,6 +383,7 @@
default => undef,
}
$arguments = ''
$_enquote_object = false
}
'FUNCTION': {
$unless_privilege = $_privilege ? {
Expand All @@ -392,8 +401,9 @@
true => 'function_exists',
default => undef,
}
$_quoted_args = join($object_arguments.map |$arg| { "\"${arg}\"" }, ',')
$arguments = "(${_quoted_args})"
$_joined_args = join($object_arguments, ',')
$arguments = "(${_joined_args})"
$_enquote_object = false
}

default: {
Expand All @@ -411,7 +421,10 @@
# }
case $_object_name {
Array: {
$_togrant_object = join($_object_name, '"."')
$_togrant_object = $_enquote_object ? {
false => join($_object_name, '.'),
default => join($_object_name, '"."'),
}
# Never put double quotes into has_*_privilege function
$_granted_object = join($_object_name, '.')
}
Expand Down Expand Up @@ -441,7 +454,10 @@
default => undef,
}

$grant_cmd = sprintf($sql_command, $_privilege, $_object_type, $_togrant_object, $arguments, $role)
$grant_cmd = $_enquote_object ? {
false => sprintf($sql_command_unquoted, $_privilege, $_object_type, $_togrant_object, $arguments, $role),
default => sprintf($sql_command, $_privilege, $_object_type, $_togrant_object, $arguments, $role),
}

postgresql_psql { "grant:${name}":
command => $grant_cmd,
Expand Down
32 changes: 32 additions & 0 deletions spec/acceptance/server/grant_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,25 @@ class { 'postgresql::server': }
require => [ Postgresql_psql['create test function'],
Postgresql::Server::Role[$user], ]
}

postgresql_psql { 'create test function with argument':
command => "CREATE FUNCTION test_func_with_arg(val integer) RETURNS integer AS 'SELECT val + 1' LANGUAGE 'sql'",
db => $db,
psql_user => $owner,
unless => "SELECT 1 FROM (SELECT format('%I.%I(%s)', ns.nspname, p.proname, oidvectortypes(p.proargtypes)) as func_with_args FROM pg_proc p INNER JOIN pg_namespace ns ON (p.pronamespace = ns.oid) WHERE ns.nspname not in ('pg_catalog', 'information_schema')) as funclist WHERE func_with_args='public.test_func_with_arg(integer)'",
require => Postgresql::Server::Database[$db],
}

postgresql::server::grant { 'grant execute on test_func_with_arg':
privilege => 'EXECUTE',
object_type => 'FUNCTION',
object_name => 'test_func_with_arg',
object_arguments => ['integer'],
db => $db,
role => $user,
require => [ Postgresql_psql['create test function with argument'],
Postgresql::Server::Role[$user], ]
}
MANIFEST
end

Expand All @@ -240,6 +259,19 @@ class { 'postgresql::server': }
end
end
end
it 'grants execute on a function with argument to a user' do
begin
if Gem::Version.new(postgresql_version) >= Gem::Version.new('9.0')
idempotent_apply(pp)

## Check that the privilege was granted to the user
psql("-d #{db} --command=\"SELECT 1 WHERE has_function_privilege('#{user}', 'test_func_with_arg(integer)', 'EXECUTE')\"", user) do |r|
expect(r.stdout).to match(%r{\(1 row\)})
expect(r.stderr).to eq('')
end
end
end
end
end
### TABLE grants
context 'table' do
Expand Down
12 changes: 6 additions & 6 deletions spec/unit/defines/server/grant_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ class {'postgresql::server':}
role: 'test',
privilege: 'execute',
object_name: 'test',
object_arguments: ['text', 'text'],
object_arguments: ['text', 'boolean'],
object_type: 'function',
}
end
Expand All @@ -262,8 +262,8 @@ class {'postgresql::server':}
it { is_expected.to contain_postgresql__server__grant('test') }
it do
is_expected.to contain_postgresql_psql('grant:test')
.with_command(%r{GRANT EXECUTE ON FUNCTION "test"\("text","text"\) TO\s* "test"}m)
.with_unless(%r{SELECT 1 WHERE has_function_privilege\('test',\s* 'test\("text","text"\)', 'EXECUTE'\)}m)
.with_command(%r{GRANT EXECUTE ON FUNCTION test\(text,boolean\) TO\s* "test"}m)
.with_unless(%r{SELECT 1 WHERE has_function_privilege\('test',\s* 'test\(text,boolean\)', 'EXECUTE'\)}m)
end
end

Expand All @@ -274,7 +274,7 @@ class {'postgresql::server':}
role: 'test',
privilege: 'execute',
object_name: ['myschema', 'test'],
object_arguments: ['text', 'text'],
object_arguments: ['text', 'boolean'],
object_type: 'function',
}
end
Expand All @@ -287,8 +287,8 @@ class {'postgresql::server':}
it { is_expected.to contain_postgresql__server__grant('test') }
it do
is_expected.to contain_postgresql_psql('grant:test')
.with_command(%r{GRANT EXECUTE ON FUNCTION "myschema"."test"\("text","text"\) TO\s* "test"}m)
.with_unless(%r{SELECT 1 WHERE has_function_privilege\('test',\s* 'myschema.test\("text","text"\)', 'EXECUTE'\)}m)
.with_command(%r{GRANT EXECUTE ON FUNCTION myschema.test\(text,boolean\) TO\s* "test"}m)
.with_unless(%r{SELECT 1 WHERE has_function_privilege\('test',\s* 'myschema.test\(text,boolean\)', 'EXECUTE'\)}m)
end
end

Expand Down