|
|
|
@ -349,6 +349,56 @@ def user_alter(cursor, module, user, password, role_attr_flags, encrypted, expir
|
|
|
|
|
if current_role_attrs[i] != new_role_attrs[i]:
|
|
|
|
|
changed = True
|
|
|
|
|
|
|
|
|
|
elif no_password_changes and role_attr_flags != '':
|
|
|
|
|
# Grab role information from pg_roles instead of pg_authid
|
|
|
|
|
select = "SELECT * FROM pg_roles where rolname=%(user)s"
|
|
|
|
|
cursor.execute(select, {"user": user})
|
|
|
|
|
# Grab current role attributes.
|
|
|
|
|
current_role_attrs = cursor.fetchone()
|
|
|
|
|
|
|
|
|
|
role_attr_flags_changing = False
|
|
|
|
|
|
|
|
|
|
if role_attr_flags:
|
|
|
|
|
role_attr_flags_dict = {}
|
|
|
|
|
for r in role_attr_flags.split(' '):
|
|
|
|
|
if r.startswith('NO'):
|
|
|
|
|
role_attr_flags_dict[r.replace('NO', '', 1)] = False
|
|
|
|
|
else:
|
|
|
|
|
role_attr_flags_dict[r] = True
|
|
|
|
|
|
|
|
|
|
for role_attr_name, role_attr_value in role_attr_flags_dict.items():
|
|
|
|
|
if current_role_attrs[PRIV_TO_AUTHID_COLUMN[role_attr_name]] != role_attr_value:
|
|
|
|
|
role_attr_flags_changing = True
|
|
|
|
|
|
|
|
|
|
if not role_attr_flags_changing:
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
alter = ['ALTER USER %(user)s' % {"user": pg_quote_identifier(user, 'role')}]
|
|
|
|
|
if role_attr_flags:
|
|
|
|
|
alter.append('WITH %s' % role_attr_flags)
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
cursor.execute(' '.join(alter))
|
|
|
|
|
except psycopg2.InternalError:
|
|
|
|
|
e = get_exception()
|
|
|
|
|
if e.pgcode == '25006':
|
|
|
|
|
# Handle errors due to read-only transactions indicated by pgcode 25006
|
|
|
|
|
# ERROR: cannot execute ALTER ROLE in a read-only transaction
|
|
|
|
|
changed = False
|
|
|
|
|
module.fail_json(msg=e.pgerror)
|
|
|
|
|
return changed
|
|
|
|
|
else:
|
|
|
|
|
raise psycopg2.InternalError(e)
|
|
|
|
|
|
|
|
|
|
# Grab new role attributes.
|
|
|
|
|
cursor.execute(select, {"user": user})
|
|
|
|
|
new_role_attrs = cursor.fetchone()
|
|
|
|
|
|
|
|
|
|
# Detect any differences between current_ and new_role_attrs.
|
|
|
|
|
for i in range(len(current_role_attrs)):
|
|
|
|
|
if current_role_attrs[i] != new_role_attrs[i]:
|
|
|
|
|
changed = True
|
|
|
|
|
|
|
|
|
|
return changed
|
|
|
|
|
|
|
|
|
|
def user_delete(cursor, user):
|
|
|
|
|