def delete(self, perform_checks=True): if perform_checks: if self.has_adresses_in_use(): raise SubnetError( "Subnet '%s/%s' cannot be deleted; it has addresses in use" % (self.subnet_ip, self.subnet_mask)) # Revoke BofhdAuthRoles associated with subnet baot = BofhdAuthOpTarget(self._db) bar = BofhdAuthRole(self._db) targets = [x['op_target_id'] for x in baot.list(entity_id=self.entity_id)] if targets: for target in targets: for x in bar.list(op_target_id=target): bar.revoke_auth(*x) bar.commit() # Remove BofhdAuthOpTarget associated with subnet for x in targets: baot.clear() try: baot.find(x) baot.delete() baot.commit() except NotFoundError: pass self._db.log_change(self.entity_id, self.const.subnet_delete, None) if self.__in_db: self.execute(""" DELETE FROM [:table schema=cerebrum name=dns_subnet] WHERE entity_id=:e_id""", {'e_id': self.entity_id}) self.__super.delete()
def set_group_owner(self, owner_id, group_id): """ This method will simply set up the Entity L{owner_id} as a C{Group-owner} of group L{group_id}. @type db: Cerebrum.Database.Database @param db: A Cerebrum database object. @type owner_id: int @param owner_id: The C{entity_id} of the owner object. @type group_id: int @param group_id: The C{group_id} of a group object. """ ar = BofhdAuthRole(self.db) aos = BofhdAuthOpSet(self.db) aot = BofhdAuthOpTarget(self.db) # Find or create group operation target try: aot.find(aot.list(entity_id=group_id, target_type=self.co.auth_target_type_group )[0]['op_target_id']) except IndexError: aot.populate(group_id, self.co.auth_target_type_group) aot.write_db() # Find the 'Group-owner' OpSet to get its entity_id aos.find_by_name('Group-owner') if not len(ar.list(owner_id, aos.op_set_id, aot.op_target_id)): ar.grant_auth(owner_id, aos.op_set_id, aot.op_target_id) return True return False
def set_group_owner(self, owner_id, group_id): """ This method will simply set up the Entity L{owner_id} as a C{Group-owner} of group L{group_id}. @type db: Cerebrum.Database.Database @param db: A Cerebrum database object. @type owner_id: int @param owner_id: The C{entity_id} of the owner object. @type group_id: int @param group_id: The C{group_id} of a group object. """ ar = BofhdAuthRole(self.db) aos = BofhdAuthOpSet(self.db) aot = BofhdAuthOpTarget(self.db) # Find or create group operation target try: aot.find( aot.list(entity_id=group_id, target_type=self.co.auth_target_type_group)[0] ['op_target_id']) except IndexError: aot.populate(group_id, self.co.auth_target_type_group) aot.write_db() # Find the 'Group-owner' OpSet to get its entity_id aos.find_by_name('Group-owner') if not len(ar.list(owner_id, aos.op_set_id, aot.op_target_id)): ar.grant_auth(owner_id, aos.op_set_id, aot.op_target_id) return True return False
def clean_opsets(db, opsets): """ Remove opsets not defined in `opsets.operation_sets`. """ operation_sets = getattr(opsets, 'operation_sets', dict()) if not operation_sets: raise OpsetConfigError("No opsets defined in operation_sets!") co = Factory.get('Constants')(db) baos = BofhdAuthOpSet(db) bar = BofhdAuthRole(db) for op_set_id, name in baos.list(): if name not in operation_sets.keys(): logger.info('Opset %s is no longer defined', name) baos.clear() baos.find(op_set_id) for op_code, op_id, _ in baos.list_operations(): logger.info( 'Deleting operation for opset %s: op_code=%s op_id=%s', baos.name, six.text_type(co.AuthRoleOp(op_code)), op_id) baos.del_operation(op_code, op_id) for role in bar.list(op_set_id=op_set_id): logger.info('Revoking %s for %s on %s', baos.name, role['entity_id'], role['op_target_id']) bar.revoke_auth(**role) logger.info('Deleting opset %s', name) baos.delete()
def _list_access(self, target_type, target_name=None, empty_result="None"): target_id, target_type, target_auth = self._get_access_id( target_type, target_name) ret = [] ar = BofhdAuthRole(self.db) aos = BofhdAuthOpSet(self.db) for r in self._get_auth_op_target(target_id, target_type, any_attr=True): attr = str(r['attr'] or '') for r2 in ar.list(op_target_id=r['op_target_id']): aos.clear() aos.find(r2['op_set_id']) ety = self._get_entity(ident=r2['entity_id']) ret.append({ 'opset': aos.name, 'attr': attr, 'type': six.text_type(self.const.EntityType(ety.entity_type)), 'name': self._get_name_from_object(ety), }) ret.sort(lambda a, b: (cmp(a['opset'], b['opset']) or cmp(a['name'], b['name']))) return ret or empty_result
def remove_target_permissions(entity_id, db): """Remove all permissions (group owner/moderator) GIVEN TO entity_id. FIXME: what if entity_id is a group owner? If we yank it, the group remains ownerless. Cf bofhd_virthome_cmds.py:__remove_auth_role. """ ar = BofhdAuthRole(db) aot = BofhdAuthOpTarget(db) for r in ar.list(entity_id): ar.revoke_auth(entity_id, r['op_set_id'], r['op_target_id']) # Also remove targets if this was the last reference from # auth_role. remaining = ar.list(op_target_id=r['op_target_id']) if len(remaining) == 0: aot.clear() aot.find(r['op_target_id']) aot.delete()
def revoke_group_auth(self, account, opset_name, group): """ Removes L{account_id} access type L{opset_name} over group L{group_id}. This can be used to remove admin and moderator access to groups. @type account: self.account_class @param account: The account that should be granted access @type opset_name: str @param opset_name: The name of the operation set (type of access) @type group: self.group_class @param group: The group that L{account} should be given access to @rtype: bool @return: True if access was revoked, False if access didn't exist. """ assert opset_name in GROUP_AUTH_OPSETS assert hasattr(account, 'entity_id') assert hasattr(group, 'entity_id') ar = BofhdAuthRole(self.db) aos = BofhdAuthOpSet(self.db) aos.find_by_name(opset_name) aot = self.find_or_create_op_target(group.entity_id, self.co.auth_target_type_group) assert account.np_type in (self.co.fedaccount_type, self.co.account_program) assert aot.target_type == self.co.auth_target_type_group roles = list(ar.list(account.entity_id, aos.op_set_id, aot.op_target_id)) if len(roles) == 0: return False # No permissions to remove ar.revoke_auth(account.entity_id, aos.op_set_id, aot.op_target_id) # If that was the last permission for this op_target, kill op_target if len(list(ar.list(op_target_id=aot.op_target_id))) == 0: aot.delete() return True # Permissions removed
def _revoke_auth(self, entity_id, opset, target_id, target_type, attr, entity_name, target_name): op_target_id = self._get_auth_op_target(target_id, target_type, attr) if not op_target_id: raise CerebrumError( "No one has matching access to {}".format(target_name)) ar = BofhdAuthRole(self.db) rows = ar.list(entity_id, opset.op_set_id, op_target_id) if len(rows) == 0: return "%s doesn't have %s access to %s %s" % ( entity_name, opset.name, six.text_type(target_type), target_name) ar.revoke_auth(entity_id, opset.op_set_id, op_target_id) # See if the op_target has any references left, delete it if not. rows = ar.list(op_target_id=op_target_id) if len(rows) == 0: aot = BofhdAuthOpTarget(self.db) aot.find(op_target_id) aot.delete() return "OK, revoked %s access for %s from %s %s" % ( opset.name, entity_name, six.text_type(target_type), target_name)
def remove_auth_roles(self, entity_id): """ This method will remove all authorization roles that has been given to an entity. It will also remove any remaining authorization targets that no longer have auth roles pointing to it as a result. @type entity_id: int @param entity_id: The entity_id of an object. """ ar = BofhdAuthRole(self.db) aot = BofhdAuthOpTarget(self.db) # Remove all auth-roles the entity have over other targets for target in ar.list(entity_ids=entity_id): ar.revoke_auth(entity_id, target['op_set_id'], target['op_target_id']) # Remove auth-target if there aren't any more auth-roles pointing # to it remaining = ar.list(op_target_id=target['op_target_id']) if len(remaining) == 0: aot.clear() aot.find(target['op_target_id']) aot.delete()
def _grant_auth(self, entity_id, opset, target_id, target_type, attr, entity_name, target_name): op_target_id = self._get_auth_op_target(target_id, target_type, attr, create=True) ar = BofhdAuthRole(self.db) rows = ar.list(entity_id, opset.op_set_id, op_target_id) if len(rows) == 0: ar.grant_auth(entity_id, opset.op_set_id, op_target_id) return "OK, granted %s access %s to %s %s" % ( entity_name, opset.name, six.text_type(target_type), target_name) return "%s already has %s access to %s %s" % ( entity_name, opset.name, six.text_type(target_type), target_name)
def remove_permissions_on_target(entity_id, db): """Remove all permissions GRANTED ON entity_id. remote_target_permissions() removes permissions held by entity_id. This function removes permissions held by other on entity_id. Cf bofhd_virthome_cmds.py:__remove_auth_target. """ ar = BofhdAuthRole(db) aot = BofhdAuthOpTarget(db) for r in aot.list(entity_id=entity_id): aot.clear() aot.find(r['op_target_id']) # We remove all auth_role entries pointing to this entity_id # first. for role in ar.list(op_target_id=r["op_target_id"]): ar.revoke_auth(role['entity_id'], role['op_set_id'], r['op_target_id']) aot.delete()
def grant_group_auth(self, account, opset_name, group): """ Grants L{entity_id} access type L{opset_name} over group L{group_id}. This can be used to give admin and moderator access to groups. @type account: self.account_class @param account: The account that should be granted access @type opset_name: str @param opset_name: The name of the operation set (type of access) @type group: self.group_class @param group: The group that L{account} should be given access to @rtype: bool @return: True if access was granted, False if access already exists """ assert opset_name in GROUP_AUTH_OPSETS assert hasattr(account, 'entity_id') assert hasattr(group, 'entity_id') ar = BofhdAuthRole(self.db) aos = BofhdAuthOpSet(self.db) aot = self.find_or_create_op_target(group.entity_id, self.co.auth_target_type_group) aos.find_by_name(opset_name) assert account.np_type in (self.co.fedaccount_type, self.co.account_program) assert hasattr(aot, 'op_target_id') # Must be populated roles = list(ar.list(account.entity_id, aos.op_set_id, aot.op_target_id)) if len(roles) == 0: ar.grant_auth(account.entity_id, aos.op_set_id, aot.op_target_id) return True # Access granted return False # Already had access
def remove_auth_targets(self, entity_id, target_type=None): """ This method will remove authorization targets of type L{target_type} that points to the L{entity_id}. If L{target_type} is None, all targets regardless of type will be removed. @type entity_id: int @param entity_id: The entity_id of an object. @type target_type: str @param target_type: The target type of the authorization target """ ar = BofhdAuthRole(self.db) aot = BofhdAuthOpTarget(self.db) for target in aot.list(entity_id=entity_id, target_type=target_type): aot.clear() aot.find(target['op_target_id']) # Before the target is removed, we must remove all roles that # grants access to the target. for role in ar.list(op_target_id=target["op_target_id"]): ar.revoke_auth(role['entity_id'], role['op_set_id'], target['op_target_id']) aot.delete()
def access_list(self, operator, owner, target_type=None): """ List everything an account or group can operate on. Only direct ownership is reported: the entities an account can access due to group memberships will not be listed. This does not include unpersonal users owned by groups. :param operator: operator in bofh session :param owner: str name of owner object :param target_type: the type of the target :return: List of everything an account or group can operate on """ ar = BofhdAuthRole(self.db) aot = BofhdAuthOpTarget(self.db) aos = BofhdAuthOpSet(self.db) co = self.const owner_id = self.util.get_target(owner, default_lookup="group", restrict_to=[]).entity_id ret = [] for role in ar.list(owner_id): aos.clear() aos.find(role['op_set_id']) for r in aot.list(target_id=role['op_target_id']): if target_type is not None and r['target_type'] != target_type: continue if r['entity_id'] is None: target_name = "N/A" elif r['target_type'] == co.auth_target_type_maildomain: # FIXME: EmailDomain is not an Entity. ed = Email.EmailDomain(self.db) try: ed.find(r['entity_id']) except (Errors.NotFoundError, ValueError): self.logger.warn("Non-existing entity (e-mail domain) " "in auth_op_target {}:{:d}".format( r['target_type'], r['entity_id'])) continue target_name = ed.email_domain_name elif r['target_type'] == co.auth_target_type_ou: ou = self.OU_class(self.db) try: ou.find(r['entity_id']) except (Errors.NotFoundError, ValueError): self.logger.warn("Non-existing entity (ou) in " "auth_op_target %s:%d" % (r['target_type'], r['entity_id'])) continue target_name = "%02d%02d%02d (%s)" % ( ou.fakultet, ou.institutt, ou.avdeling, ou.short_name) elif r['target_type'] == co.auth_target_type_dns: s = Subnet(self.db) # TODO: should Subnet.find() support ints as input? try: s.find('entity_id:%s' % r['entity_id']) except (Errors.NotFoundError, ValueError, SubnetError): self.logger.warn("Non-existing entity (subnet) in " "auth_op_target %s:%d" % (r['target_type'], r['entity_id'])) continue target_name = "%s/%s" % (s.subnet_ip, s.subnet_mask) else: try: ety = self._get_entity(ident=r['entity_id']) target_name = self._get_name_from_object(ety) except (Errors.NotFoundError, ValueError): self.logger.warn("Non-existing entity in " "auth_op_target %s:%d" % (r['target_type'], r['entity_id'])) continue ret.append({ 'opset': aos.name, 'target_type': r['target_type'], 'target': target_name, 'attr': r['attr'] or "", }) ret.sort(lambda a, b: (cmp(a['target_type'], b['target_type']) or cmp( a['target'], b['target']))) return ret