Skip to content
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

postgresql_privs: fix schema quoting #382

Merged
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
bugfixes:
- postgresql_privs - fix quoting of the ``schema`` parameter in SQL statements (https://github.com/ansible-collections/community.postgresql/pull/382).
12 changes: 5 additions & 7 deletions plugins/modules/postgresql_privs.py
Original file line number Diff line number Diff line change
Expand Up @@ -817,6 +817,7 @@ def manipulate_privs(self, obj_type, privs, objs, orig_objs, roles, target_roles
if not objs:
return False

quoted_schema_qualifier = '"%s"' % schema_qualifier.replace('"', '""') if schema_qualifier else None
Andersson007 marked this conversation as resolved.
Show resolved Hide resolved
# obj_ids: quoted db object identifiers (sometimes schema-qualified)
if obj_type in ('function', 'procedure'):
obj_ids = []
Expand All @@ -825,9 +826,9 @@ def manipulate_privs(self, obj_type, privs, objs, orig_objs, roles, target_roles
f, args = obj.split('(', 1)
except Exception:
raise Error('Illegal function / procedure signature: "%s".' % obj)
obj_ids.append('"%s"."%s"(%s' % (schema_qualifier, f, args))
obj_ids.append('%s."%s"(%s' % (quoted_schema_qualifier, f, args))
elif obj_type in ['table', 'sequence', 'type']:
obj_ids = ['"%s"."%s"' % (schema_qualifier, o) for o in objs]
obj_ids = ['%s."%s"' % (quoted_schema_qualifier, o) for o in objs]
else:
obj_ids = ['"%s"' % o for o in objs]

Expand All @@ -846,7 +847,7 @@ def manipulate_privs(self, obj_type, privs, objs, orig_objs, roles, target_roles
# and privs was escaped when it was parsed
# Note: Underscores are replaced with spaces to support multi-word obj_type
if orig_objs is not None:
set_what = '%s ON %s %s' % (','.join(privs), orig_objs, schema_qualifier)
set_what = '%s ON %s %s' % (','.join(privs), orig_objs, quoted_schema_qualifier)
else:
set_what = '%s ON %s %s' % (','.join(privs), obj_type.replace('_', ' '), ','.join(obj_ids))

Expand Down Expand Up @@ -875,17 +876,14 @@ def manipulate_privs(self, obj_type, privs, objs, orig_objs, roles, target_roles
if target_roles:
as_who = ','.join('"%s"' % r for r in target_roles)

if schema_qualifier:
schema_qualifier = '"%s"' % schema_qualifier

status_before = get_status(objs)

query = QueryBuilder(state) \
.for_objtype(obj_type) \
.with_grant_option(grant_option) \
.for_whom(for_whom) \
.as_who(as_who) \
.for_schema(schema_qualifier) \
.for_schema(quoted_schema_qualifier) \
.set_what(set_what) \
.for_objs(objs) \
.usage_on_types(usage_on_types) \
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ db_user_with_dots2: role.with.dots2
db_name_with_hyphens: ansible-db
db_user_with_hyphens: ansible-db-user
db_schema_with_hyphens: ansible-db-schema
db_schema_with_dot: test.schema
db_schema_with_quote: 'TEST_schema"'
db_session_role1: session_role1
db_session_role2: session_role2
dangerous_name: 'curious.anonymous"; SELECT * FROM information_schema.tables; --'
Original file line number Diff line number Diff line change
Expand Up @@ -1476,6 +1476,114 @@
that:
- result is not changed

##############
# Issue https://github.com/ansible-collections/community.postgresql/issues/381
- name: create schemas with special names
become: true
become_user: "{{ pg_user }}"
postgresql_schema:
login_user: "{{ pg_user }}"
login_password: password
db: "{{ db_name }}"
name: '"{{ item }}"'
state: present
loop:
- "{{ db_schema_with_dot|replace('\"', '\"\"') }}"
- "{{ db_schema_with_quote|replace('\"', '\"\"') }}"
register: result
- assert:
that:
- result is changed
- name: create tables in schemas with special names
become: true
become_user: "{{ pg_user }}"
postgresql_table:
login_user: "{{ pg_user }}"
login_password: password
db: "{{ db_name }}"
name: '"{{ item }}"."test.table.name"'
columns: []
loop:
- "{{ db_schema_with_dot|replace('\"', '\"\"') }}"
- "{{ db_schema_with_quote|replace('\"', '\"\"') }}"
register: result
- assert:
that:
- result is changed
- name: grant privileges on all tables in schemas with special names
become: yes
become_user: "{{ pg_user }}"
postgresql_privs:
login_user: "{{ pg_user }}"
login_db: "{{ db_name }}"
roles: PUBLIC
objs: ALL_IN_SCHEMA
type: table
privs: SELECT
schema: "{{ item }}"
loop:
- "{{ db_schema_with_dot }}"
- "{{ db_schema_with_quote }}"
register: result
- assert:
that:
- result is changed
- name: grant privileges on some table in schemas with special names
become: yes
become_user: "{{ pg_user }}"
postgresql_privs:
login_user: "{{ pg_user }}"
login_db: "{{ db_name }}"
roles: PUBLIC
objs: 'test.table.name'
type: table
privs: SELECT
schema: "{{ item }}"
loop:
- "{{ db_schema_with_dot }}"
- "{{ db_schema_with_quote }}"
register: result
- assert:
that:
- result is changed
- name: check permissions on tables in schemas with special names
become: true
become_user: "{{ pg_user }}"
postgresql_query:
login_user: "{{ pg_user }}"
db: "{{ db_name }}"
query: |
select true as granted from information_schema.role_table_grants
where table_schema=%s and table_name='test.table.name' and privilege_type='SELECT' and grantee='PUBLIC'
positional_args:
- "{{ item }}"
loop:
- "{{ db_schema_with_dot }}"
- "{{ db_schema_with_quote }}"
register: result
- assert:
that:
- 'result.results|length == 2'
- 'result.results[0].rowcount == 1'
- 'not result.results[0].failed'
- 'result.results[1].rowcount == 1'
- 'not result.results[1].failed'
- name: cleanup test schemas with special names
become: true
become_user: "{{ pg_user }}"
postgresql_schema:
login_user: "{{ pg_user }}"
login_password: password
db: "{{ db_name }}"
name: '"{{ item }}"'
state: absent
cascade_drop: true
loop:
- "{{ db_schema_with_dot|replace('\"', '\"\"') }}"
- "{{ db_schema_with_quote|replace('\"', '\"\"') }}"
register: result


##############
# Issue https://github.com/ansible-collections/community.postgresql/issues/332
- name: Test community.postgresql issue 332 grant usage
Expand Down