From 91d9767cc3a030e91d7424ac687c63ad73b9a11b Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya Date: Wed, 23 Jun 2010 23:16:25 -0700 Subject: [PATCH 1/4] Installer now creates global developer role --- nova/auth/slap.sh | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/nova/auth/slap.sh b/nova/auth/slap.sh index 277ae2bc..90dc7a9d 100755 --- a/nova/auth/slap.sh +++ b/nova/auth/slap.sh @@ -221,6 +221,12 @@ objectClass: simpleSecurityObject # create the sysadmin entry +dn: cn=developers,ou=Groups,dc=example,dc=com +objectclass: groupOfNames +cn: developers +description: IT admin group +member: uid=admin,ou=Users,dc=example,dc=com + dn: cn=sysadmins,ou=Groups,dc=example,dc=com objectclass: groupOfNames cn: sysadmins From 4e005255aebc27fa35f770403c323acf92886352 Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya Date: Wed, 23 Jun 2010 23:16:25 -0700 Subject: [PATCH 2/4] Fix error message for checking for projectmanager role --- nova/auth/users.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/nova/auth/users.py b/nova/auth/users.py index 6997596a..1896abd9 100644 --- a/nova/auth/users.py +++ b/nova/auth/users.py @@ -349,7 +349,9 @@ class UserManager(object): def has_role(self, user, role, project=None): with LDAPWrapper() as conn: - if project and role == 'projectmanager': + if role == 'projectmanager': + if not project: + raise exception.Error("Must specify project") return self.is_project_manager(user, project) global_role = conn.has_role(User.safe_id(user), From 96ff7a0bab30561b214edf2819eded021a5d5465 Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya Date: Wed, 23 Jun 2010 23:16:25 -0700 Subject: [PATCH 3/4] Fix deletion of user when he is the last member of the group --- nova/auth/users.py | 41 +++++++++++++++++++++++++++-------------- 1 file changed, 27 insertions(+), 14 deletions(-) diff --git a/nova/auth/users.py b/nova/auth/users.py index 1896abd9..e2e18175 100644 --- a/nova/auth/users.py +++ b/nova/auth/users.py @@ -515,6 +515,14 @@ class LDAPWrapper(object): return None return objects[0] + def find_dns(self, dn, query = None): + try: + res = self.conn.search_s(dn, ldap.SCOPE_SUBTREE, query) + except Exception: + return [] + # just return the dns + return [x[0] for x in res] + def find_objects(self, dn, query = None): try: res = self.conn.search_s(dn, ldap.SCOPE_SUBTREE, query) @@ -539,9 +547,11 @@ class LDAPWrapper(object): attrs = self.find_objects(tree, '(&(objectclass=groupOfNames)(!(objectclass=NovaProject)))') return [self.__to_group(attr) for attr in attrs] - def find_groups_with_member(self, tree, dn): - attrs = self.find_objects(tree, '(&(objectclass=groupOfNames)(member=%s))' % dn ) - return [self.__to_group(attr) for attr in attrs] + def find_group_dns_with_member(self, tree, uid): + dns = self.find_dns(tree, + '(&(objectclass=groupOfNames)(member=%s))' % + self.__uid_to_dn(uid) ) + return dns def find_user(self, uid): attr = self.find_object(self.__uid_to_dn(uid), '(objectclass=novaUser)') @@ -717,29 +727,32 @@ class LDAPWrapper(object): raise exception.NotFound("User %s can't be removed from the group because the user doesn't exist" % (uid,)) if not self.is_in_group(uid, group_dn): raise exception.NotFound("User %s is not a member of the group" % (uid,)) + self._safe_remove_from_group(group_dn, uid) + + def _safe_remove_from_group(self, group_dn, uid): + # FIXME(vish): what if deleted user is a project manager? attr = [ (ldap.MOD_DELETE, 'member', self.__uid_to_dn(uid)) ] try: self.conn.modify_s(group_dn, attr) except ldap.OBJECT_CLASS_VIOLATION: - logging.debug("Attempted to remove the last member of a group. Deleting the group instead.") + logging.debug("Attempted to remove the last member of a group. " + "Deleting the group at %s instead." % group_dn ) self.delete_group(group_dn) def remove_from_all(self, uid): - # FIXME(vish): what if deleted user is a project manager? if not self.user_exists(uid): raise exception.NotFound("User %s can't be removed from all because the user doesn't exist" % (uid,)) dn = self.__uid_to_dn(uid) - attr = [ - (ldap.MOD_DELETE, 'member', dn) - ] - roles = self.find_groups_with_member(FLAGS.role_ldap_subtree, dn) - for role in roles: - self.conn.modify_s('cn=%s,%s' % (role.id, FLAGS.role_ldap_subtree), attr) - projects = self.find_groups_with_member(FLAGS.project_ldap_subtree, dn) - for project in projects: - self.conn.modify_s('cn=%s,%s' % (project.id, FLAGS.project_ldap_subtree), attr) + role_dns = self.find_group_dns_with_member( + FLAGS.role_ldap_subtree, uid) + for role_dn in role_dns: + self._safe_remove_from_group(role_dn, uid) + project_dns = self.find_group_dns_with_member( + FLAGS.project_ldap_subtree, uid) + for project_dn in project_dns: + self._safe_remove_from_group(project_dn, uid) def create_key_pair(self, uid, key_name, public_key, fingerprint): """create's a public key in the directory underneath the user""" From 522876baaaa45ee26f96f00219675bb32b89381d Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya Date: Fri, 25 Jun 2010 10:09:21 -0700 Subject: [PATCH 4/4] style cleanup --- nova/auth/users.py | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/nova/auth/users.py b/nova/auth/users.py index e2e18175..fae0d095 100644 --- a/nova/auth/users.py +++ b/nova/auth/users.py @@ -515,13 +515,13 @@ class LDAPWrapper(object): return None return objects[0] - def find_dns(self, dn, query = None): + def find_dns(self, dn, query=None): try: res = self.conn.search_s(dn, ldap.SCOPE_SUBTREE, query) except Exception: return [] - # just return the dns - return [x[0] for x in res] + # just return the DNs + return [dn for dn, attributes in res] def find_objects(self, dn, query = None): try: @@ -529,7 +529,7 @@ class LDAPWrapper(object): except Exception: return [] # just return the attributes - return [x[1] for x in res] + return [attributes for dn, attributes in res] def find_users(self): attrs = self.find_objects(FLAGS.user_ldap_subtree, '(objectclass=novaUser)') @@ -550,7 +550,7 @@ class LDAPWrapper(object): def find_group_dns_with_member(self, tree, uid): dns = self.find_dns(tree, '(&(objectclass=groupOfNames)(member=%s))' % - self.__uid_to_dn(uid) ) + self.__uid_to_dn(uid)) return dns def find_user(self, uid): @@ -731,9 +731,7 @@ class LDAPWrapper(object): def _safe_remove_from_group(self, group_dn, uid): # FIXME(vish): what if deleted user is a project manager? - attr = [ - (ldap.MOD_DELETE, 'member', self.__uid_to_dn(uid)) - ] + attr = [(ldap.MOD_DELETE, 'member', self.__uid_to_dn(uid))] try: self.conn.modify_s(group_dn, attr) except ldap.OBJECT_CLASS_VIOLATION: @@ -746,11 +744,11 @@ class LDAPWrapper(object): raise exception.NotFound("User %s can't be removed from all because the user doesn't exist" % (uid,)) dn = self.__uid_to_dn(uid) role_dns = self.find_group_dns_with_member( - FLAGS.role_ldap_subtree, uid) + FLAGS.role_ldap_subtree, uid) for role_dn in role_dns: self._safe_remove_from_group(role_dn, uid) project_dns = self.find_group_dns_with_member( - FLAGS.project_ldap_subtree, uid) + FLAGS.project_ldap_subtree, uid) for project_dn in project_dns: self._safe_remove_from_group(project_dn, uid)