Exemple #1
0
 def attach(self, obj, lo):
     # add univentionPolicyReference if neccessary
     oc = lo.get(obj.dn, ['objectClass'])
     if 'univentionPolicyReference' not in oc.get('objectClass', []):
         try:
             lo.modify(obj.dn,
                       [('objectClass', '', 'univentionPolicyReference')])
         except:
             logger.warning(
                 'Objectclass univentionPolicyReference cannot be added to %r',
                 obj)
             return
     # add the missing policy
     pl = lo.get(obj.dn, ['univentionPolicyReference'])
     logger.info('Attaching %r to %r', self, obj)
     if self.dn.lower() not in map(lambda x: x.lower(),
                                   pl.get('univentionPolicyReference', [])):
         modlist = [('univentionPolicyReference', '', self.dn)]
         try:
             lo.modify(obj.dn, modlist)
         except:
             logger.warning('Policy %s cannot be referenced to %r', self,
                            obj)
     else:
         logger.info('Already attached!')
Exemple #2
0
	def add_domain_controllers(self, lo):
		logger.info('School.add_domain_controllers(): ou_name=%r', self.name)
		school_dcs = ucr.get('ucsschool/ldap/default/dcs', 'edukativ').split()
		for dc in school_dcs:
			administrative = dc == 'verwaltung'
			dc_name = self.get_dc_name(administrative=administrative)
			server = AnyComputer.get_first_udm_obj(lo, 'cn=%s' % escape_filter_chars(dc_name))
			logger.info('School.add_domain_controllers(): administrative=%r  dc_name=%s  self.dc_name=%r  server=%r', administrative, dc_name, self.dc_name, server)
			if not server and not self.dc_name:
				if administrative:
					administrative_type = 'administrative'
				else:
					administrative_type = 'educational'
				group_dn = self.get_administrative_group_name(administrative_type, ou_specific=True, as_dn=True)
				try:
					hostlist = lo.get(group_dn, ['uniqueMember']).get('uniqueMember', [])
				except ldap.NO_SUCH_OBJECT:
					hostlist = []
				except Exception, e:
					logger.error('cannot read %s: %s', group_dn, e)
					return

				if hostlist:
					continue  # if at least one DC has control over this OU then jump to next 'school_dcs' item ==> do not create default slave objects

				self.create_dc_slave(lo, dc_name, administrative=administrative)

			dhcp_service = self.get_dhcp_service(dc_name)
			dhcp_service.create(lo)
			dhcp_service.add_server(dc_name, lo)
			return True
Exemple #3
0
 def _alter_udm_obj(self, udm_obj):
     super(SchoolComputer, self)._alter_udm_obj(udm_obj)
     inventory_numbers = self.get_inventory_numbers()
     if inventory_numbers:
         udm_obj['inventoryNumber'] = inventory_numbers
     ipv4_network = self.get_ipv4_network()
     if ipv4_network:
         if self._ip_is_set_to_subnet(ipv4_network):
             logger.info(
                 'IP was set to subnet. Unsetting it on the computer so that UDM can do some magic: Assign next free IP!'
             )
             udm_obj['ip'] = ''
         else:
             udm_obj['ip'] = str(ipv4_network.ip)
     # set network after ip. Otherwise UDM does not do any
     #   nextIp magic...
     network = self.get_network()
     if network:
         # reset network, so that next line triggers free ip
         udm_obj.old_network = None
         try:
             udm_obj['network'] = network.dn
         except nextFreeIp:
             logger.error(
                 'Tried to set IP automatically, but failed! %r is full',
                 network)
             raise nextFreeIp(
                 _('There are no free addresses left in the subnet!'))
Exemple #4
0
 def move_without_hooks(self, lo, udm_obj, force=False):
     if udm_obj is None:
         udm_obj = self.get_udm_object(lo)
     if udm_obj is None:
         logger.warning('No UDM object found to move from (%r)', self)
         return False
     if self.supports_school() and self.get_school_obj(lo) is None:
         logger.warn('%r wants to move itself to a not existing school',
                     self)
         return False
     logger.info('Moving %r to %r', udm_obj.dn, self)
     if udm_obj.dn == self.dn:
         logger.warning('%r wants to move to its own DN!', self)
         return False
     if force or self._meta.allow_school_change:
         try:
             self.do_move(udm_obj, lo)
         finally:
             self.invalidate_cache()
         self.set_dn(self.dn)
     else:
         logger.warning(
             'Would like to move %s to %r. But it is not allowed!',
             udm_obj.dn, self)
         return False
     return True
Exemple #5
0
    def create_without_hooks(self, lo, validate):
        if self.exists(lo):
            return False
        logger.info('Creating %r', self)

        if validate:
            self.validate(lo)
            if self.errors:
                raise ValidationError(self.errors.copy())

        pos = udm_uldap.position(ucr.get('ldap/base'))
        container = self.position
        if not container:
            logger.error('%r cannot determine a container. Unable to create!',
                         self)
            return False
        try:
            pos.setDn(container)
            udm_obj = udm_modules.get(self._meta.udm_module).object(
                None, lo, pos, superordinate=self.get_superordinate(lo))
            udm_obj.open()

            # here is the real logic
            self.do_create(udm_obj, lo)

            # get it fresh from the database (needed for udm_obj._exists ...)
            self.set_dn(self.dn)
            logger.info('%r successfully created', self)
            return True
        finally:
            self.invalidate_cache()
Exemple #6
0
    def do_school_change(self, udm_obj, lo, old_school):
        try:
            exam_user = ExamStudent.from_student_dn(lo, old_school,
                                                    self.old_dn)
        except noObject as exc:
            logger.info('No exam user for %r found: %s', self.old_dn, exc)
        else:
            logger.info('Removing exam user %r', exam_user.dn)
            exam_user.remove(lo)

        super(Student, self).do_school_change(udm_obj, lo, old_school)
Exemple #7
0
	def add_host_to_dc_group(self, lo):
		logger.info('School.add_host_to_dc_group(): ou_name=%r  dc_name=%r', self.name, self.dc_name)
		if self.dc_name:
			dc = SchoolDCSlave(name=self.dc_name, school=self.name)
			dc.create(lo)
			dc_udm_obj = dc.get_udm_object(lo)
			groups = self.get_administrative_group_name('educational', ou_specific='both', as_dn=True)
			for grp in groups:
				if grp not in dc_udm_obj['groups']:
					dc_udm_obj['groups'].append(grp)
			dc_udm_obj.modify()
Exemple #8
0
 def remove_from_groups_of_school(self, school, lo):
     for cls in (SchoolClass, WorkGroup, SchoolGroup):
         for group in cls.get_all(
                 lo, school, filter_format('uniqueMember=%s', (self.dn, ))):
             try:
                 group.users.remove(self.dn)
             except ValueError:
                 pass
             else:
                 logger.info('Removing %r from group %r of school %r.',
                             self.dn, group.dn, school)
                 group.modify(lo)
Exemple #9
0
	def create(self, lo, validate=True):
		logger.info('Creating %r', self)
		pos = udm_uldap.position(ucr.get('ldap/base'))
		pos.setDn(self.position)
		udm_obj = udm_modules.get(self._meta.udm_module).object(None, lo, pos)
		udm_obj.open()
		udm_obj['name'] = self.name
		try:
			self.do_create(udm_obj, lo)
		except objectExists as exc:
			return exc.args[0]
		else:
			return udm_obj.dn
Exemple #10
0
    def modify_without_hooks(self, lo, validate=True, move_if_necessary=None):
        logger.info('Modifying %r', self)

        if move_if_necessary is None:
            move_if_necessary = self._meta.allow_school_change

        if validate:
            self.validate(lo, validate_unlikely_changes=True)
            if self.errors:
                raise ValidationError(self.errors.copy())

        udm_obj = self.get_udm_object(lo)
        if not udm_obj:
            logger.info('%s does not exist!', self.old_dn)
            return False

        try:
            old_attrs = deepcopy(udm_obj.info)
            self.do_modify(udm_obj, lo)
            # get it fresh from the database
            self.set_dn(self.dn)
            udm_obj = self.get_udm_object(lo)
            same = old_attrs == udm_obj.info
            if move_if_necessary:
                if udm_obj.dn != self.dn:
                    if self.move_without_hooks(lo, udm_obj, force=True):
                        same = False
            if same:
                logger.info('%r not modified. Nothing changed', self)
            else:
                logger.info('%r successfully modified', self)
            # return not same
            return True
        finally:
            self.invalidate_cache()
Exemple #11
0
    def do_modify(self, udm_obj, lo):
        self.create_mail_domain(lo)
        self.password = self.password or None

        removed_schools = set(udm_obj['school']) - set(self.schools)
        if removed_schools:
            # change self.schools back, so schools can be removed by remove_from_school()
            self.schools = udm_obj['school']
        for removed_school in removed_schools:
            logger.info('Removing %r from school %r...', self, removed_school)
            if not self.remove_from_school(removed_school, lo):
                logger.error('Error removing %r from school %r.', self,
                             removed_school)
                return False

        mandatory_groups = self.groups_used(lo)
        for group_dn in udm_obj['groups'][:]:
            logger.debug('Checking group %s for removal', group_dn)
            if group_dn not in mandatory_groups:
                logger.debug('Group not mandatory! Part of a school?')
                try:
                    school_class = SchoolClass.from_dn(group_dn, None, lo)
                except noObject:
                    logger.debug('No. Leaving it alone...')
                    continue
                logger.debug('Yes, part of %s!', school_class.school)
                if school_class.school not in self.school_classes:
                    continue  # if the key isn't set we don't change anything to the groups. to remove the groups it has to be an empty list
                classes = self.school_classes[school_class.school]
                remove = school_class.name not in classes and school_class.get_relative_name(
                ) not in classes
                if remove:
                    logger.debug('Removing it!')
                    udm_obj['groups'].remove(group_dn)
                else:
                    logger.debug(
                        'Leaving it alone: Part of own school and either non-school class or new school classes were not defined at all'
                    )
        for group_dn in mandatory_groups:
            logger.debug('Checking group %s for adding', group_dn)
            if group_dn not in udm_obj['groups']:
                logger.debug('Group is not yet part of the user. Adding...')
                udm_obj['groups'].append(group_dn)
        return super(User, self).do_modify(udm_obj, lo)
Exemple #12
0
 def do_create(self, udm_obj, lo):
     gid = self.school_group.get_udm_object(lo)['gidNumber']
     udm_obj['host'] = self.get_server_fqdn(lo)
     udm_obj['path'] = self.get_share_path()
     udm_obj['writeable'] = '1'
     udm_obj['sambaWriteable'] = '1'
     udm_obj['sambaBrowseable'] = '1'
     udm_obj['sambaForceGroup'] = '+%s' % self.name
     udm_obj['sambaCreateMode'] = '0770'
     udm_obj['sambaDirectoryMode'] = '0770'
     udm_obj['owner'] = '0'
     udm_obj['group'] = gid
     udm_obj['directorymode'] = '0770'
     if ucr.is_false('ucsschool/default/share/nfs', True):
         try:
             udm_obj.options.remove('nfs')  # deactivate NFS
         except ValueError:
             pass
     logger.info('Creating share on "%s"', udm_obj['host'])
     return super(Share, self).do_create(udm_obj, lo)
Exemple #13
0
    def from_udm_obj(
        cls, udm_obj, school, lo
    ):  # Design fault. school is part of the DN or the ucsschoolSchool attribute.
        '''Creates a new instance with attributes of the udm_obj.
		Uses get_class_for_udm_obj()
		'''
        cls.init_udm_module(lo)
        klass = cls.get_class_for_udm_obj(udm_obj, school)
        if klass is None:
            logger.warning(
                'UDM object %s does not correspond to a class in UCS school lib!',
                udm_obj.dn)
            raise UnknownModel(udm_obj.dn, cls)
        if klass is not cls:
            logger.info('UDM object %s is not %s, but actually %s', udm_obj.dn,
                        cls.__name__, klass.__name__)
            if not issubclass(klass, cls):
                # security!
                # ExamStudent must not be converted into Teacher/Student/etc.,
                # SchoolClass must not be converted into ComputerRoom
                # while Group must be converted into ComputerRoom, etc. and User must be converted into Student, etc.
                raise WrongModel(udm_obj.dn, klass, cls)
            return klass.from_udm_obj(udm_obj, school, lo)
        udm_obj.open()
        attrs = {
            'school': cls.get_school_from_dn(udm_obj.dn) or school
        }  # TODO: is this adjustment okay?
        for name, attr in cls._attributes.iteritems():
            if attr.udm_name:
                udm_value = udm_obj[attr.udm_name]
                if udm_value == '':
                    udm_value = None
                attrs[name] = udm_value
        obj = cls(**deepcopy(attrs))
        obj.set_dn(udm_obj.dn)
        obj._udm_obj_searched = True
        obj._udm_obj = udm_obj
        return obj
Exemple #14
0
	def create_dc_slave(self, lo, name, administrative=False):
		if administrative and not self.shall_create_administrative_objects():
			logger.warning('Not creating %s: An administrative DC shall not be created as by UCR variable %r', name, 'ucsschool/ldap/noneducational/create/objects')
			return False
		if not self.exists(lo):
			logger.error('%r does not exist. Cannot create %s', self, name)
			return False
		if administrative:
			groups = self.get_administrative_group_name('administrative', ou_specific='both', as_dn=True)
		else:
			groups = self.get_administrative_group_name('educational', ou_specific='both', as_dn=True)
		logger.debug('DC shall become member of %r', groups)

		dc = SchoolDCSlave(name=name, school=self.name, groups=groups)
		if dc.exists(lo):
			logger.info('%r exists. Setting groups, do not move to %r!', dc, self)
			# call dc.move() if really necessary to move
			return dc.modify(lo, move_if_necessary=False)
		else:
			existing_host = AnyComputer.get_first_udm_obj(lo, 'cn=%s' % escape_filter_chars(name))
			if existing_host:
				logger.error('Given host name "%s" is already in use and no domaincontroller slave system. Please choose another name.', name)
				return False
			return dc.create(lo)
Exemple #15
0
    def do_school_change(self, udm_obj, lo, old_school):
        super(User, self).do_school_change(udm_obj, lo, old_school)
        school = self.school

        logger.info('User is part of the following groups: %r',
                    udm_obj['groups'])
        self.remove_from_groups_of_school(old_school, lo)
        self._udm_obj_searched = False
        self.school_classes.pop(old_school, None)
        udm_obj = self.get_udm_object(lo)
        udm_obj['primaryGroup'] = self.primary_group_dn(lo)
        groups = set(udm_obj['groups'])
        at_least_groups = set(self.groups_used(lo))
        if (groups | at_least_groups) != groups:
            udm_obj['groups'] = list(groups | at_least_groups)
        subdir = self.get_roleshare_home_subdir()
        udm_obj['unixhome'] = '/home/' + os.path.join(subdir, self.name)
        samba_home = self.get_samba_home_path(lo)
        if samba_home:
            udm_obj['sambahome'] = samba_home
        profile_path = self.get_profile_path(lo)
        if profile_path:
            udm_obj['profilepath'] = profile_path
        home_drive = self.get_samba_home_drive()
        if home_drive is not None:
            udm_obj['homedrive'] = home_drive
        script_path = self.get_samba_netlogon_script_path()
        if script_path is not None:
            udm_obj['scriptpath'] = script_path
        if udm_obj['departmentNumber'] == old_school:
            udm_obj['departmentNumber'] = school
        if school not in udm_obj['school']:
            udm_obj['school'].append(school)
        if old_school in udm_obj['school']:
            udm_obj['school'].remove(old_school)
        udm_obj.modify(ignore_license=True)
Exemple #16
0
 def remove_without_hooks(self, lo):
     logger.info('Deleting %r', self)
     udm_obj = self.get_udm_object(lo)
     if udm_obj:
         try:
             udm_obj.remove(remove_childs=True)
             udm_objects.performCleanup(udm_obj)
             self.set_dn(None)
             logger.info('%r successfully removed', self)
             return True
         finally:
             self.invalidate_cache()
     logger.info('%r does not exist!', self)
     return False
Exemple #17
0
    def move_without_hooks(self, lo, udm_obj=None, force=False):
        try:
            if udm_obj is None:
                try:
                    udm_obj = self.get_only_udm_obj(
                        lo, 'cn=%s' % escape_filter_chars(self.name))
                except MultipleObjectsError:
                    logger.error(
                        'Found more than one DC Slave with hostname "%s"',
                        self.name)
                    return False
                if udm_obj is None:
                    logger.error('Cannot find DC Slave with hostname "%s"',
                                 self.name)
                    return False
            old_dn = udm_obj.dn
            school = self.get_school_obj(lo)
            group_dn = school.get_administrative_group_name('educational',
                                                            ou_specific=True,
                                                            as_dn=True)
            if group_dn not in udm_obj['groups']:
                logger.error('%r has no LDAP access to %r', self, school)
                return False
            if old_dn == self.dn:
                logger.info(
                    'DC Slave "%s" is already located in "%s" - stopping here',
                    self.name, self.school)
            self.set_dn(old_dn)
            if self.exists_outside_school(lo):
                if not force:
                    logger.error('DC Slave "%s" is located in another OU - %s',
                                 self.name, udm_obj.dn)
                    logger.error('Use force=True to override')
                    return False
            if school is None:
                logger.error(
                    'Cannot move DC Slave object - School does not exist: %r',
                    school)
                return False
            self.modify_without_hooks(lo)
            if school.class_share_file_server == old_dn:
                school.class_share_file_server = self.dn
            if school.home_share_file_server == old_dn:
                school.home_share_file_server = self.dn
            school.modify_without_hooks(lo)

            removed = False
            # find dhcp server object by checking all dhcp service objects
            for dhcp_service in AnyDHCPService.get_all(lo, None):
                for dhcp_server in dhcp_service.get_servers(lo):
                    if dhcp_server.name == self.name and not dhcp_server.dn.endswith(
                            ',%s' % school.dn):
                        dhcp_server.remove(lo)
                        removed = True

            if removed:
                own_dhcp_service = school.get_dhcp_service()

                dhcp_server = DHCPServer(name=self.name,
                                         school=self.school,
                                         dhcp_service=own_dhcp_service)
                dhcp_server.create(lo)

            logger.info('Move complete')
            logger.warning('The DC Slave has to be rejoined into the domain!')
        finally:
            self.invalidate_cache()
        return True
Exemple #18
0
 def do_school_change(self, udm_obj, lo, old_school):
     logger.info('Going to move %r from school %r to %r', self.old_dn,
                 old_school, self.school)
Exemple #19
0
 def get_ipv4_subnet(self):
     network_str = '%s/%s' % (self.name, self.subnet_mask)
     try:
         return ipaddr.IPv4Network(network_str)
     except ValueError as exc:
         logger.info('%r is no valid IPv4Network:\n%s', network_str, exc)
Exemple #20
0
    def add_server(self, dc_name, lo, force_dhcp_server_move=False):
        """
		Create the given DHCP server within the DHCP service. If the DHCP server
		object already exists somewhere else within the LDAP tree, it may be moved
		to the DHCP service.

		PLEASE NOTE:
		In multiserver environments an existing DHCP server object is always
		moved to the current DHCP service. In single server environments the
		DHCP server object is *ONLY* moved, if the UCR variable dhcpd/ldap/base
		matches to the current DHCP service.
		"""
        from ucsschool.lib.models.school import School

        # create dhcp-server if not exsistant
        school = School.cache(self.school)
        dhcp_server = DHCPServer(name=dc_name,
                                 school=school.name,
                                 dhcp_service=self)
        existing_dhcp_server_dn = DHCPServer.find_any_dn_with_name(dc_name, lo)
        if existing_dhcp_server_dn:
            logger.info('DHCP server %s exists!', existing_dhcp_server_dn)
            old_dhcp_server_container = lo.parentDn(existing_dhcp_server_dn)
            dhcpd_ldap_base = ucr.get('dhcpd/ldap/base', '')
            # only move if
            # - forced via kwargs OR
            # - in multiserver environments OR
            # - desired dhcp server DN matches with UCR config
            if force_dhcp_server_move or not ucr.is_true(
                    'ucsschool/singlemaster',
                    False) or dhcp_server.dn.endswith(',%s' % dhcpd_ldap_base):
                # move if existing DN does not match with desired DN
                if existing_dhcp_server_dn != dhcp_server.dn:
                    # move existing dhcp server object to OU/DHCP service
                    logger.info(
                        'DHCP server %s not in school %r! Removing and creating new one at %s!',
                        existing_dhcp_server_dn, school, dhcp_server.dn)
                    old_superordinate = DHCPServer.find_udm_superordinate(
                        existing_dhcp_server_dn, lo)
                    old_dhcp_server = DHCPServer.from_dn(
                        existing_dhcp_server_dn,
                        None,
                        lo,
                        superordinate=old_superordinate)
                    old_dhcp_server.remove(lo)
                    dhcp_server.create(lo)

            # copy subnets
            # find local interfaces
            interfaces = []
            for interface_name in set([
                    key.split('/')[1] for key in ucr.keys()
                    if key.startswith('interfaces/eth')
            ]):
                try:
                    address = ipaddr.IPv4Network('%s/%s' % (
                        ucr['interfaces/%s/address' % interface_name],
                        ucr['interfaces/%s/netmask' % interface_name],
                    ))
                    interfaces.append(address)
                except ValueError as exc:
                    logger.info('Skipping invalid interface %s:\n%s',
                                interface_name, exc)
            subnet_dns = DHCPSubnet.find_all_dns_below_base(
                old_dhcp_server_container, lo)
            for subnet_dn in subnet_dns:
                dhcp_service = DHCPSubnet.find_udm_superordinate(subnet_dn, lo)
                dhcp_subnet = DHCPSubnet.from_dn(subnet_dn,
                                                 self.school,
                                                 lo,
                                                 superordinate=dhcp_service)
                subnet = dhcp_subnet.get_ipv4_subnet()
                if subnet in interfaces:  # subnet matches any local subnet
                    logger.info('Creating new DHCPSubnet from %s', subnet_dn)
                    new_dhcp_subnet = DHCPSubnet(**dhcp_subnet.to_dict())
                    new_dhcp_subnet.dhcp_service = self
                    new_dhcp_subnet.position = new_dhcp_subnet.get_own_container(
                    )
                    new_dhcp_subnet.set_dn(new_dhcp_subnet.dn)
                    new_dhcp_subnet.create(lo)
                else:
                    logger.info('Skipping non-local subnet %s', subnet)
        else:
            logger.info('No DHCP server named %s found! Creating new one!',
                        dc_name)
            dhcp_server.create(lo)