Beispiel #1
0
def get_groups_moderators(groups):
    aot = BofhdAuthOpTarget(db)
    ar = BofhdAuthRole(db)
    aos = BofhdAuthOpSet(db)
    co = Factory.get('Constants')(db)    
    en = Factory.get('Entity')(db)

    for group in groups:
        group_id = group[0]
        targets = []
        for row in aot.list(target_type = 'group', entity_id = group_id):
            targets.append(int(row['op_target_id']))
        for row in ar.list_owners(targets):
            aos.clear()
            aos.find(row['op_set_id'])
            id = int(row['entity_id'])
            en.clear()
            en.find(id)
            entity_id = int(en.entity_id)
            en.clear()
            ent = en.get_subclassed_object(entity_id)
            if ent.entity_type == co.entity_account:
                owner = ent.account_name
            elif ent.entity_type == co.entity_group:
                owner = ent.group_name
            else:
                owner = '#%d' % id
            group.append(" ".join([str(co.EntityType(ent.entity_type)), 
                                   owner, aos.name]))            
Beispiel #2
0
    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
Beispiel #3
0
def get_groups_moderators(groups):
    aot = BofhdAuthOpTarget(db)
    ar = BofhdAuthRole(db)
    aos = BofhdAuthOpSet(db)
    co = Factory.get('Constants')(db)
    en = Factory.get('Entity')(db)

    for group in groups:
        group_id = group[0]
        targets = []
        for row in aot.list(target_type='group', entity_id=group_id):
            targets.append(int(row['op_target_id']))
        for row in ar.list_owners(targets):
            aos.clear()
            aos.find(row['op_set_id'])
            id = int(row['entity_id'])
            en.clear()
            en.find(id)
            entity_id = int(en.entity_id)
            en.clear()
            ent = en.get_subclassed_object(entity_id)
            if ent.entity_type == co.entity_account:
                owner = ent.account_name
            elif ent.entity_type == co.entity_group:
                owner = ent.group_name
            else:
                owner = '#%d' % id
            group.append(" ".join(
                [str(co.EntityType(ent.entity_type)), owner, aos.name]))
Beispiel #4
0
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 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
Beispiel #7
0
    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
Beispiel #8
0
    def write_db(self):
        """Write PosixUser instance to database, in addition to the personal
        file group. As long as L{gid_id} is not set, it gets set to the
        account's personal file group instead.

        """
        if not self.gid_id:
            # Create the PosixGroup first, to get its entity_id
            # TODO: Should we handle that self.pg could not be populated when
            # we're here? When could gid_id be none without running populate?
            self.pg.write_db()
            # We'll need to set this here, as the groups entity_id is
            # created when we write to the DB.
            self.gid_id = self.pg.entity_id

        ret = self.__super.write_db()

        # Become a member of the group:
        if not hasattr(self.pg, "entity_id"):
            self.pg.find(self.gid_id)
        if not self.pg.has_member(self.entity_id):
            self.pg.add_member(self.entity_id)

        # If the dfg is not a personal group we are done now:
        # TODO: check trait_personal_dfg instead or in addition?
        if self.account_name != self.pg.group_name:
            return ret

        # Set the personal file group trait
        if not self.pg.get_trait(self.const.trait_personal_dfg):
            self.pg.populate_trait(self.const.trait_personal_dfg, target_id=self.entity_id)
            self.pg.write_db()

        # Register the posixuser as owner of the group, if not already set
        op_target = BofhdAuthOpTarget(self._db)
        if not op_target.list(entity_id=self.pg.entity_id, target_type="group"):
            op_target.populate(self.pg.entity_id, "group")
            op_target.write_db()
            op_set = BofhdAuthOpSet(self._db)
            op_set.find_by_name(cereconf.BOFHD_AUTH_GROUPMODERATOR)
            role = BofhdAuthRole(self._db)
            role.grant_auth(self.entity_id, op_set.op_set_id, op_target.op_target_id)

        # Syncronizing the groups spreads with the users
        mapping = {
            int(self.const.spread_uio_nis_user): int(self.const.spread_uio_nis_fg),
            int(self.const.spread_uio_ad_account): int(self.const.spread_uio_ad_group),
            int(self.const.spread_ifi_nis_user): int(self.const.spread_ifi_nis_fg),
        }
        user_spreads = [int(r["spread"]) for r in self.get_spread()]
        group_spreads = [int(r["spread"]) for r in self.pg.get_spread()]
        for uspr, gspr in mapping.iteritems():
            if uspr in user_spreads:
                if gspr not in group_spreads:
                    self.pg.add_spread(gspr)
            elif gspr in group_spreads:
                self.pg.delete_spread(gspr)
        return ret
Beispiel #9
0
 def _group_make_owner(self, owner, target):
     op_set = BofhdAuthOpSet(self.db)
     op_set.find_by_name(cereconf.BOFHD_AUTH_GROUPMODERATOR)
     op_target = BofhdAuthOpTarget(self.db)
     op_target.populate(target.entity_id, 'group')
     op_target.write_db()
     role = BofhdAuthRole(self.db)
     role.grant_auth(owner.entity_id, op_set.op_set_id,
                     op_target.op_target_id)
Beispiel #10
0
 def _set_owner_of_group(self, group):
     op_target = BofhdAuthOpTarget(self._db)
     if not op_target.list(entity_id=group.entity_id, target_type='group'):
         op_target.populate(group.entity_id, 'group')
         op_target.write_db()
         op_set = BofhdAuthOpSet(self._db)
         op_set.find_by_name(cereconf.BOFHD_AUTH_GROUPMODERATOR)
         role = BofhdAuthRole(self._db)
         role.grant_auth(self.entity_id,
                         op_set.op_set_id,
                         op_target.op_target_id)
def main():
    """Remove invalid auth data."""
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument(
        '-c', '--commit',
        action='store_true',
        dest='commit',
        default=False,
        help='Actually remove the invalid auth data.'
    )

    Cerebrum.logutils.options.install_subparser(parser)
    args = parser.parse_args()
    Cerebrum.logutils.autoconf('cronjob', args)

    logger.info('START {0}'.format(parser.prog))
    db = Factory.get('Database')()
    db.cl_init(change_program='clean_invalid_bofh_auth_data.py')

    baot = BofhdAuthOpTarget(db)
    bar = BofhdAuthRole(db)
    bar_count = bar.count_invalid()
    baot_count = baot.count_invalid()

    try:
        bar.remove_invalid()
        baot.remove_invalid()

    except DatabaseError as e:
        db.rollback()
        logger.error(
            'Error removing invalid auth data {0}. Rolling back any changes'
            .format(e))
        raise

    bar_count_after = bar.count_invalid()
    baot_count_after = baot.count_invalid()

    logger.info('Removing {0} invalid entries in auth_roles'.format(
        bar_count - bar_count_after))
    logger.info('Removing {0} invalid entries in auth_op_targets'.format(
        baot_count - baot_count_after))

    if args.commit:
        logger.info('Committing changes.')
        db.commit()
    else:
        logger.info('Rolling back changes.')
        db.rollback()

    logger.info('DONE {0}'.format(parser.prog))
Beispiel #12
0
 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)
Beispiel #13
0
    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()
Beispiel #14
0
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()
Beispiel #15
0
    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
Beispiel #16
0
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()
Beispiel #17
0
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()
Beispiel #18
0
    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()
Beispiel #19
0
    def group_info(self, operator, groupname):
        grp = self._get_group(groupname)
        co = self.const
        ret = [self._entity_info(grp), ]
        # find owners
        aot = BofhdAuthOpTarget(self.db)
        targets = []
        for row in aot.list(target_type='group', entity_id=grp.entity_id):
            targets.append(int(row['op_target_id']))
        ar = BofhdAuthRole(self.db)
        aos = BofhdAuthOpSet(self.db)
        for row in ar.list_owners(targets):
            aos.clear()
            aos.find(row['op_set_id'])
            id = int(row['entity_id'])
            en = self._get_entity(ident=id)
            if en.entity_type == co.entity_account:
                owner = en.account_name
            elif en.entity_type == co.entity_group:
                owner = en.group_name
            else:
                owner = '#%d' % id
            ret.append({
                'owner_type': text_type(co.EntityType(en.entity_type)),
                'owner': owner,
                'opset': aos.name,
            })

        # Count group members of different types
        members = list(grp.search_members(group_id=grp.entity_id))
        tmp = {}
        for ret_pfix, entity_type in (
                ('c_group', int(co.entity_group)),
                ('c_account', int(co.entity_account))):
            tmp[ret_pfix] = len([x for x in members
                                 if int(x["member_type"]) == entity_type])
        ret.append(tmp)
        return ret
Beispiel #20
0
    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
Beispiel #21
0
    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
Beispiel #22
0
    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()
Beispiel #23
0
    def group_info(self, operator, groupname):
        grp = self._get_group(groupname)
        co = self.const
        ret = [ self._entity_info(grp) ]
        # find owners
        aot = BofhdAuthOpTarget(self.db)
        targets = []
        for row in aot.list(target_type='group', entity_id=grp.entity_id):
            targets.append(int(row['op_target_id']))
        ar = BofhdAuthRole(self.db)
        aos = BofhdAuthOpSet(self.db)
        for row in ar.list_owners(targets):
            aos.clear()
            aos.find(row['op_set_id'])
            id = int(row['entity_id'])
            en = self._get_entity(ident=id)
            if en.entity_type == co.entity_account:
                owner = en.account_name
            elif en.entity_type == co.entity_group:
                owner = en.group_name
            else:
                owner = '#%d' % id
            ret.append({'owner_type': str(co.EntityType(en.entity_type)),
                        'owner': owner,
                        'opset': aos.name})

        # Count group members of different types
        members = list(grp.search_members(group_id=grp.entity_id))
        tmp = {}
        for ret_pfix, entity_type in (
                ('c_group', int(self.const.entity_group)),
                ('c_account', int(self.const.entity_account))):
            tmp[ret_pfix] = len([x for x in members
                                 if int(x["member_type"]) == entity_type])
        ret.append(tmp)
        return ret
Beispiel #24
0
    def grant_auth(en, gr, opset):
        """Grant authorization to a group.

        :type en: <Cerebrum.Entity.Entity>
        :param en: The entity to grant auth to.

        :type gr: <Cerebrum.Group.Group>
        :param gr: The group to grant auth on.

        :type opset: str
        :param opset: The OpSet to be granted."""
        # TODO: ._db? 'group' to op_target.populate ok? should be derived from
        # gr, but that means we'll need to do Factory.get in here... :(
        # TODO: Can this be generalized and moved to utils??
        from Cerebrum.modules.bofhd.auth import BofhdAuthOpSet, \
            BofhdAuthOpTarget, BofhdAuthRole
        op_set = BofhdAuthOpSet(en._db)
        op_set.find_by_name(opset)
        op_target = BofhdAuthOpTarget(en._db)
        op_target.populate(gr.entity_id, 'group')
        op_target.write_db()
        role = BofhdAuthRole(en._db)
        role.grant_auth(en.entity_id, op_set.op_set_id,
                        op_target.op_target_id)
Beispiel #25
0
    def grant_auth(en, gr, opset):
        """Grant authorization to a group.

        :type en: <Cerebrum.Entity.Entity>
        :param en: The entity to grant auth to.

        :type gr: <Cerebrum.Group.Group>
        :param gr: The group to grant auth on.

        :type opset: str
        :param opset: The OpSet to be granted."""
        # TODO: ._db? 'group' to op_target.populate ok? should be derived from
        # gr, but that means we'll need to do Factory.get in here... :(
        # TODO: Can this be generalized and moved to utils??
        from Cerebrum.modules.bofhd.auth import BofhdAuthOpSet, \
            BofhdAuthOpTarget, BofhdAuthRole
        op_set = BofhdAuthOpSet(en._db)
        op_set.find_by_name(opset)
        op_target = BofhdAuthOpTarget(en._db)
        op_target.populate(gr.entity_id, 'group')
        op_target.write_db()
        role = BofhdAuthRole(en._db)
        role.grant_auth(en.entity_id, op_set.op_set_id,
                        op_target.op_target_id)
Beispiel #26
0
    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 _operators_ou(self, operator):
        """Return a sequence of OUs that operator can 'see'.

        Superusers see everything.
        School IT see only the OUs where they have privileges.
        Everyone else sees nothing.
        """
        def grab_all_ous():
            return [
                int(x['ou_id'])
                for x in self.ou.search(filter_quarantined=False)
            ]

        if self.ba.is_superuser(operator.get_entity_id(), True):
            return grab_all_ous()

        if not self.ba.is_schoolit(operator.get_entity_id(), True):
            return []

        group = self.Group_class(self.db)
        # fetch all groups where operator is a member
        op_groups = [
            x['group_id']
            for x in group.search(member_id=operator.get_entity_id(),
                                  indirect_members=False)
        ]
        # fetch all permissions that these groups have
        op_targets = [
            x['op_target_id']
            for x in BofhdAuthRole(self.db).list(entity_ids=op_groups)
        ]

        # Now, finally, the permissions:
        result = list()
        for permission in BofhdAuthOpTarget(self.db).list(
                target_id=op_targets,
                target_type=self.const.auth_target_type_ou,
        ):
            if permission["entity_id"] is not None:
                result.append(int(permission["entity_id"]))
            else:
                # AHA! We have a general OU permission. Grab them all!
                return grab_all_ous()

        return result
def main():
    """Remove invalid auth data."""
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument(
        '-c', '--commit',
        action='store_true',
        dest='commit',
        default=False,
        help='Actually remove the invalid auth data.'
    )

    Cerebrum.logutils.options.install_subparser(parser)
    args = parser.parse_args()
    Cerebrum.logutils.autoconf('cronjob', args)

    logger.info('START {0}'.format(parser.prog))
    db = Factory.get('Database')()
    db.cl_init(change_program='clean_invalid_bofh_auth_data.py')

    baot = BofhdAuthOpTarget(db)
    bar = BofhdAuthRole(db)
    bar_count = bar.count_invalid()
    baot_count = baot.count_invalid()

    try:
        bar.remove_invalid()
        baot.remove_invalid()

    except DatabaseError as e:
        db.rollback()
        logger.error(
            'Error removing invalid auth data {0}. Rolling back any changes'
            .format(e))
        raise

    bar_count_after = bar.count_invalid()
    baot_count_after = baot.count_invalid()

    logger.info('Removing {0} invalid entries in auth_roles'.format(
        bar_count - bar_count_after))
    logger.info('Removing {0} invalid entries in auth_op_targets'.format(
        baot_count - baot_count_after))

    if args.commit:
        logger.info('Committing changes.')
        db.commit()
    else:
        logger.info('Rolling back changes.')
        db.rollback()

    logger.info('DONE {0}'.format(parser.prog))
Beispiel #29
0
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()
Beispiel #30
0
    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
Beispiel #31
0
 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)
Beispiel #32
0
    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()
Beispiel #33
0
from Cerebrum.Utils import Factory
from Cerebrum import Errors
from Cerebrum.modules.bofhd.auth import BofhdAuthOpSet, \
     BofhdAuthOpTarget, BofhdAuthRole

# Initialize logger
logger = Factory.get_logger('cronjob')

# Initialize database connections
db = Factory.get('Database')()
ac = Factory.get('Account')(db)
pe = Factory.get('Person')(db)
gr = Factory.get('Group')(db)
baos = BofhdAuthOpSet(db)
bar = BofhdAuthRole(db)
baot = BofhdAuthOpTarget(db)

db.cl_init(change_program="update_affiliation_groups.py")


def usage(exitcode=0):
    print """Usage:
    %s [Options]

    Update group memberships for primary accounts based on affiliations.

    Options:
    -l, --list                      List affiliations.
    -d, --dryrun                    Don't commit changes to Cerebrum db.
    -a, --affmap    <aff:group>     Specify mappings between affs and groups.
Beispiel #34
0
    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
Beispiel #35
0
    def write_db(self):
        """Write PosixUser instance to database, in addition to the personal
        file group. As long as L{gid_id} is not set, it gets set to the
        account's personal file group instead.

        """
        if not self.gid_id:
            # Create the PosixGroup first, to get its entity_id
            # TODO: Should we handle that self.pg could not be populated when
            # we're here? When could gid_id be none without running populate?
            self.pg.write_db()
            # We'll need to set this here, as the groups entity_id is
            # created when we write to the DB.
            self.gid_id = self.pg.entity_id

        ret = self.__super.write_db()

        # Become a member of the group:
        if not hasattr(self.pg, 'entity_id'):
            self.pg.find(self.gid_id)
        if not self.pg.has_member(self.entity_id):
            self.pg.add_member(self.entity_id)

        # If the dfg is not a personal group we are done now:
        # TODO: check trait_personal_dfg instead or in addition?
        if self.account_name != self.pg.group_name:
            return ret

        # Set the personal file group trait
        if not self.pg.get_trait(self.const.trait_personal_dfg):
            self.pg.populate_trait(self.const.trait_personal_dfg,
                                   target_id=self.entity_id)
            self.pg.write_db()

        # Register the posixuser as owner of the group, if not already set
        op_target = BofhdAuthOpTarget(self._db)
        if not op_target.list(entity_id=self.pg.entity_id,
                              target_type='group'):
            op_target.populate(self.pg.entity_id, 'group')
            op_target.write_db()
            op_set = BofhdAuthOpSet(self._db)
            op_set.find_by_name(cereconf.BOFHD_AUTH_GROUPMODERATOR)
            role = BofhdAuthRole(self._db)
            role.grant_auth(self.entity_id, op_set.op_set_id,
                            op_target.op_target_id)

        # Syncronizing the groups spreads with the users
        mapping = {
            int(self.const.spread_uio_nis_user):
            int(self.const.spread_uio_nis_fg),
            int(self.const.spread_uio_ad_account):
            int(self.const.spread_uio_ad_group),
            int(self.const.spread_ifi_nis_user):
            int(self.const.spread_ifi_nis_fg)
        }
        user_spreads = [int(r['spread']) for r in self.get_spread()]
        group_spreads = [int(r['spread']) for r in self.pg.get_spread()]
        for uspr, gspr in mapping.iteritems():
            if uspr in user_spreads:
                if gspr not in group_spreads:
                    self.pg.add_spread(gspr)
            elif gspr in group_spreads:
                self.pg.delete_spread(gspr)
        return ret