From 5ff957322a66dcae902aace216d9eb06d9f91d8a Mon Sep 17 00:00:00 2001 From: Marcos Diez Date: Wed, 16 Mar 2016 21:59:24 +0200 Subject: [PATCH 1/2] mongodb_user: fix checking if the roles of an oplog reader user changed --- database/misc/mongodb_user.py | 39 ++++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/database/misc/mongodb_user.py b/database/misc/mongodb_user.py index e58857586eb..bc636f52397 100644 --- a/database/misc/mongodb_user.py +++ b/database/misc/mongodb_user.py @@ -193,6 +193,43 @@ def load_mongocnf(): return creds + + +def check_if_roles_changed(uinfo, roles, db_name): +# The reason for such complicated method is a user which can read the oplog on a replicaset +# This user must have access to the local DB, but since this DB does not have users +# and is not synchronized among replica sets, the user must be stored on the admin db +# { +# "_id" : "admin.oplog_reader", +# "user" : "oplog_reader", +# "db" : "admin", +# "roles" : [ +# { +# "role" : "read", +# "db" : "local" +# } +# ] +# } + + def make_sure_roles_are_a_list_of_dict(roles, db_name): + output = list() + for role in roles: + if isinstance(role, basestring): + new_role = { "role": role, "db": db_name } + output.append(new_role) + else: + output.append(role) + return output + + roles_as_list_of_dict = make_sure_roles_are_a_list_of_dict(roles, db_name) + uinfo_roles = uinfo.get('roles', []) + + if sorted(roles_as_list_of_dict) == sorted(uinfo_roles): + return False + return True + + + # ========================================= # Module execution. # @@ -265,7 +302,7 @@ def main(): uinfo = user_find(client, user, db_name) if update_password != 'always' and uinfo: password = None - if list(map((lambda x: x['role']), uinfo.get('roles', []))) == roles: + if not check_if_roles_changed(uinfo, roles, db_name): module.exit_json(changed=False, user=user) try: From 7ec5209e18439fd984e1b4705e83dc3a2509185c Mon Sep 17 00:00:00 2001 From: Marcos Diez Date: Wed, 16 Mar 2016 22:07:58 +0200 Subject: [PATCH 2/2] mongodb_user.py: changes on comments --- database/misc/mongodb_user.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/database/misc/mongodb_user.py b/database/misc/mongodb_user.py index bc636f52397..829dcb7e6b5 100644 --- a/database/misc/mongodb_user.py +++ b/database/misc/mongodb_user.py @@ -196,17 +196,18 @@ def load_mongocnf(): def check_if_roles_changed(uinfo, roles, db_name): -# The reason for such complicated method is a user which can read the oplog on a replicaset -# This user must have access to the local DB, but since this DB does not have users +# We must be aware of users which can read the oplog on a replicaset +# Such users must have access to the local DB, but since this DB does not store users credentials # and is not synchronized among replica sets, the user must be stored on the admin db +# Therefore their structure is the following : # { # "_id" : "admin.oplog_reader", # "user" : "oplog_reader", -# "db" : "admin", +# "db" : "admin", # <-- admin DB # "roles" : [ # { # "role" : "read", -# "db" : "local" +# "db" : "local" # <-- local DB # } # ] # }