Example #1
0
	def create_without_hooks(self, lo, validate):
		district = self.get_district()
		if district:
			ou = OU(name=district)
			ou.position = ucr.get('ldap/base')
			ou.create(lo, False)

		# setting class_share_file_server and home_share_file_server:
		# 1. set to None
		# 2. create school
		# 3. (maybe) create file_servers <- that is why this is necessary
		# 4. set file_servers
		# 5. modify school
		saved_class_share_file_server = self.class_share_file_server
		saved_home_share_file_server = self.home_share_file_server
		self.class_share_file_server = None
		self.home_share_file_server = None

		try:
			success = super(School, self).create_without_hooks(lo, validate)
			if not success:
				logger.warning('Creating %r failed (maybe it already exists?)! Trying to set it up nonetheless', self)
				self.modify_without_hooks(lo)

			# In a single server environment the default DHCP container must
			# be set to the DHCP container in the school ou. Otherwise newly
			# imported computers have the DHCP objects in the wrong DHCP container
			if ucr.is_true('ucsschool/singlemaster', False):
				if not ucr.get('dhcpd/ldap/base'):
					handler_set(['dhcpd/ldap/base=cn=dhcp,%s' % (self.dn)])
					ucr.load()

			self.create_default_containers(lo)
			self.create_default_groups(lo)
			self.add_host_to_dc_group(lo)
			if not self.add_domain_controllers(lo):
				return False
			if self.dc_name_administrative:
				self.create_dc_slave(lo, self.dc_name_administrative, administrative=True)
				dhcp_service = self.get_dhcp_service(self.dc_name_administrative)
				dhcp_service.create(lo)
				dhcp_service.add_server(self.dc_name_administrative, lo)
		finally:
			logger.debug('Resetting share file servers from None to %r and %r', saved_home_share_file_server, saved_class_share_file_server)
			self.class_share_file_server = saved_class_share_file_server
			self.home_share_file_server = saved_home_share_file_server
		self.class_share_file_server = self.get_class_share_file_server(lo)
		self.home_share_file_server = self.get_home_share_file_server(lo)
		logger.debug('Now it is %r and %r - %r should be modified accordingly', self.home_share_file_server, self.class_share_file_server, self)
		self.modify_without_hooks(lo)

		# if requested, then create dhcp_dns policy that clears univentionDhcpDomainNameServers at OU level
		# to prevent problems with "wrong" DHCP DNS policy connected to ldap base
		if ucr.is_true('ucsschool/import/generate/policy/dhcp/dns/clearou', False):
			policy = DHCPDNSPolicy(name='dhcp-dns-clear', school=self.name, empty_attributes=['univentionDhcpDomainNameServers'])
			policy.create(lo)
			policy.attach(self, lo)

		return success
Example #2
0
	def create_default_groups(self, lo):
		# DC groups
		administrative_group_container = 'cn=ucsschool,cn=groups,%s' % ucr.get('ldap/base')

		# DC-Edukativnetz
		# OU%s-DC-Edukativnetz
		# Member-Edukativnetz
		# OU%s-Member-Edukativnetz
		administrative_group_names = self.get_administrative_group_name('educational', domain_controller='both', ou_specific='both')
		if self.shall_create_administrative_objects():
			administrative_group_names.extend(self.get_administrative_group_name('administrative', domain_controller='both', ou_specific='both'))  # same with Verwaltungsnetz
		for administrative_group_name in administrative_group_names:
			group = BasicGroup.cache(name=administrative_group_name, container=administrative_group_container)
			group.create(lo)

		# cn=ouadmins
		admin_group_container = 'cn=ouadmins,cn=groups,%s' % ucr.get('ldap/base')
		group = BasicGroup.cache(self.group_name('admins', 'admins-'), container=admin_group_container)
		group.create(lo)
		group.add_umc_policy(self.get_umc_policy_dn('admins'), lo)
		try:
			udm_obj = group.get_udm_object(lo)
		except noObject:
			logger.error('Could not load OU admin group %r for adding "school" value', group.dn)
		else:
			admin_option = 'ucsschoolAdministratorGroup'
			if admin_option not in udm_obj.options:
				udm_obj.options.append(admin_option)
			udm_obj['school'] = [self.name]
			udm_obj.modify()

		# cn=schueler
		group = Group.cache(self.group_name('pupils', 'schueler-'), self.name)
		group.create(lo)
		group.add_umc_policy(self.get_umc_policy_dn('pupils'), lo)

		# cn=lehrer
		group = Group.cache(self.group_name('teachers', 'lehrer-'), self.name)
		group.create(lo)
		group.add_umc_policy(self.get_umc_policy_dn('teachers'), lo)

		# cn=mitarbeiter
		if self.shall_create_administrative_objects():
			group = Group.cache(self.group_name('staff', 'mitarbeiter-'), self.name)
			group.create(lo)
			group.add_umc_policy(self.get_umc_policy_dn('staff'), lo)

		if ucr.is_true('ucsschool/import/attach/policy/default-umc-users', True):
			# cn=Domain Users %s
			group = Group.cache("Domain Users %s" % (self.name,), self.name)
			group.create(lo)
			group.add_umc_policy("cn=default-umc-users,cn=UMC,cn=policies,%s" % (ucr.get('ldap/base'),), lo)
Example #3
0
 def create_without_hooks(self, lo, validate):
     # prepare LDAP: create containers where this basic group lives if necessary
     container_dn = self.get_own_container()[:-len(ucr.get('ldap/base')) -
                                             1]
     containers = str2dn(container_dn)
     super_container_dn = ucr.get('ldap/base')
     for container_info in reversed(containers):
         dn_part, cn = container_info[0][0:2]
         if dn_part.lower() == 'ou':
             container = OU(name=cn)
         else:
             container = Container(name=cn, school='', group_path='1')
         container.position = super_container_dn
         super_container_dn = container.create(lo, False)
     return super(BasicGroup, self).create_without_hooks(lo, validate)
Example #4
0
    def get_only_udm_obj(cls, lo, filter_str, superordinate=None, base=None):
        '''Returns the one UDM object of class cls._meta.udm_module that
		matches a given filter.
		If more than one is found, a MultipleObjectsError is raised
		If none is found, None is returned
		'''
        cls.init_udm_module(lo)
        if cls._meta.udm_filter:
            filter_str = '(&(%s)(%s))' % (cls._meta.udm_filter, filter_str)
        logger.debug('Getting %s UDM object by filter: %s', cls.__name__,
                     filter_str)
        objs = udm_modules.lookup(cls._meta.udm_module,
                                  None,
                                  lo,
                                  scope='sub',
                                  base=base or ucr.get('ldap/base'),
                                  filter=str(filter_str),
                                  superordinate=superordinate)
        if len(objs) == 0:
            return None
        if len(objs) > 1:
            raise MultipleObjectsError(objs)
        obj = objs[0]
        obj.open()
        return obj
Example #5
0
 def get_students_groups(self):
     prefix = ucr.get('ucsschool/ldap/default/groupprefix/pupils',
                      'schueler-')
     return [
         self.get_group_dn('%s%s' % (prefix, school), school)
         for school in self.schools
     ]
Example #6
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
Example #7
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()
Example #8
0
 def get_staff_groups(self):
     prefix = ucr.get('ucsschool/ldap/default/groupprefix/staff',
                      'mitarbeiter-')
     return [
         self.get_group_dn('%s%s' % (prefix, school), school)
         for school in self.schools
     ]
Example #9
0
 def from_student_dn(cls, lo, school, dn):
     examUserPrefix = ucr.get('ucsschool/ldap/default/userprefix/exam',
                              'exam-')
     dn = 'uid=%s%s,%s' % (escape_dn_chars(examUserPrefix),
                           explode_dn(dn,
                                      True)[0], cls.get_container(school))
     return cls.from_dn(dn, school, lo)
Example #10
0
 def get_teachers_groups(self):
     prefix = ucr.get('ucsschool/ldap/default/groupprefix/teachers',
                      'lehrer-')
     return [
         self.get_group_dn('%s%s' % (prefix, school), school)
         for school in self.schools
     ]
Example #11
0
def check_configuration(config):
	if not config.get("sourceUID"):
		raise InitialisationError("No sourceUID was specified.")
	if not config["input"].get("type"):
		raise InitialisationError("No input:type was specified.")
	if "user_deletion" in config:
		raise InitialisationError("The 'user_deletion' configuration key is deprecated. Please set 'deletion_grace_period'.")
	for role in ('default', 'staff',  'student', 'teacher', 'teacher_and_staff'):
		try:
			username_max_length = config["username"]["max_length"][role]
		except KeyError:
			continue
		if username_max_length < 4:
			raise InitialisationError(
				"Configuration value of username:max_length:{} must be higher than 3.".format(role)
			)
	exam_user_prefix_length = len(ucr.get("ucsschool/ldap/default/userprefix/exam", "exam-"))
	student_username_max_length = config["username"]["max_length"].get("student", 20 - exam_user_prefix_length)
	if student_username_max_length > 20 - exam_user_prefix_length:
		raise InitialisationError(
			"Configuration value of username:max_length:student must be {} or less.".format(20 - exam_user_prefix_length)
		)
	for role in ('default', 'staff', 'teacher', 'teacher_and_staff'):
		username_max_length = config["username"]["max_length"].get(role, 20)
		if username_max_length > 20:
			raise InitialisationError(
				"Configuration value of username:max_length:{} must be 20 or less.".format(role)
			)
Example #12
0
	def get_all(cls, lo, filter_str=None, easy_filter=False, respect_local_oulist=True):
		schools = super(School, cls).get_all(lo, school=None, filter_str=filter_str, easy_filter=easy_filter)
		oulist = ucr.get('ucsschool/local/oulist')
		if oulist and respect_local_oulist:
			logger.debug('All Schools: Schools overridden by UCR variable ucsschool/local/oulist')
			ous = [x.strip() for x in oulist.split(',')]
			schools = [school for school in schools if school.name in ous]
		return cls._filter_local_schools(schools, lo)
Example #13
0
 def find_any_dn_with_name(cls, name, lo):
     logger.debug('Searching first dhcpServer with cn=%s', name)
     try:
         dn = lo.searchDn(filter=filter_format(
             '(&(objectClass=dhcpServer)(cn=%s))', [name]),
                          base=ucr.get('ldap/base'))[0]
     except IndexError:
         dn = None
     logger.debug('... %r found', dn)
     return dn
Example #14
0
	def get_dc_name(self, administrative=False, or_fallback=True):
		if ucr.is_true('ucsschool/singlemaster', False):
			return ucr.get('hostname')
		elif self.dc_name:
			if administrative:
				return '%sv' % self.dc_name
			else:
				return self.dc_name
		else:
			if or_fallback:
				return self.get_dc_name_fallback(administrative=administrative)
			else:
				return None
Example #15
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
Example #16
0
 def get_samba_home_path(self, lo):
     school = School.cache(self.school)
     # if defined then use UCR value
     ucr_variable = ucr.get('ucsschool/import/set/sambahome')
     if ucr_variable is not None:
         samba_home_path = r'\\%s' % ucr_variable.strip('\\')
     # in single server environments the master is always the fileserver
     elif ucr.is_true('ucsschool/singlemaster', False):
         samba_home_path = r'\\%s' % ucr.get('hostname')
     # if there's a cached result then use it
     elif school.dn not in self._samba_home_path_cache:
         samba_home_path = None
         # get windows home server from OU object
         school = self.get_school_obj(lo)
         home_share_file_server = school.home_share_file_server
         if home_share_file_server:
             samba_home_path = r'\\%s' % self.get_name_from_dn(
                 home_share_file_server)
         self._samba_home_path_cache[school.dn] = samba_home_path
     else:
         samba_home_path = self._samba_home_path_cache[school.dn]
     if samba_home_path is not None:
         return r'%s\%s' % (samba_home_path, self.name)
Example #17
0
	def get_share_fileserver_dn(self, set_by_self, lo):
		if set_by_self:
			set_by_self = self.get_name_from_dn(set_by_self) or set_by_self
		hostname = set_by_self or self.get_dc_name()
		if hostname == self.get_dc_name_fallback():
			# does not matter if exists or not - dc object will be created later
			host = SchoolDC(name=hostname, school=self.name)
			return host.dn

		host = AnyComputer.get_first_udm_obj(lo, 'cn=%s' % escape_filter_chars(hostname))
		if host:
			return host.dn
		else:
			logger.warning('Could not find %s. Using this host as ShareFileServer ("%s").', hostname, ucr.get('hostname'))
			return ucr.get('ldap/hostdn')
Example #18
0
 def validate(self, value):
     super(DCName, self).validate(value)
     if value:
         regex = re.compile('^[a-zA-Z0-9](([a-zA-Z0-9-]*)([a-zA-Z0-9]$))?$')
         if not regex.match(value):
             raise ValueError(_('Invalid Domain Controller name'))
         if ucr.is_true('ucsschool/singlemaster', False):
             if len(value) > 12:
                 raise ValueError(
                     _('A valid NetBIOS hostname can not be longer than 12 characters.'
                       ))
             if sum([len(value), 1, len(ucr.get('domainname', ''))]) > 63:
                 raise ValueError(
                     _('The length of fully qualified domain name is greater than 63 characters.'
                       ))
Example #19
0
 def get_profile_path(self, lo):
     ucr_variable = ucr.get('ucsschool/import/set/serverprofile/path')
     if ucr_variable is not None:
         return ucr_variable
     school = School.cache(self.school)
     if school.dn not in self._profile_path_cache:
         profile_path = r'%s\%%USERNAME%%\windows-profiles\default'
         for computer in AnyComputer.get_all(
                 lo, self.school,
                 'univentionService=Windows Profile Server'):
             profile_path = profile_path % (r'\\%s' % computer.name)
             break
         else:
             profile_path = profile_path % '%LOGONSERVER%'
         self._profile_path_cache[school.dn] = profile_path
     return self._profile_path_cache[school.dn]
Example #20
0
    def get_server_fqdn(self, lo):
        domainname = ucr.get('domainname')
        school = self.get_school_obj(lo)
        school_dn = school.dn

        # fetch serverfqdn from OU
        result = lo.get(school_dn, ['ucsschoolClassShareFileServer'])
        if result:
            server_domain_name = lo.get(
                result['ucsschoolClassShareFileServer'][0],
                ['associatedDomain'])
            if server_domain_name:
                server_domain_name = server_domain_name['associatedDomain'][0]
            else:
                server_domain_name = domainname
            result = lo.get(result['ucsschoolClassShareFileServer'][0], ['cn'])
            if result:
                return '%s.%s' % (result['cn'][0], server_domain_name)

        # get alternative server (defined at ou object if a dc slave is responsible for more than one ou)
        ou_attr_ldap_access_write = lo.get(school_dn,
                                           ['univentionLDAPAccessWrite'])
        alternative_server_dn = None
        if len(ou_attr_ldap_access_write) > 0:
            alternative_server_dn = ou_attr_ldap_access_write[
                'univentionLDAPAccessWrite'][0]
            if len(ou_attr_ldap_access_write) > 1:
                logger.warning(
                    'more than one corresponding univentionLDAPAccessWrite found at ou=%s',
                    self.school)

        # build fqdn of alternative server and set serverfqdn
        if alternative_server_dn:
            alternative_server_attr = lo.get(alternative_server_dn, ['uid'])
            if len(alternative_server_attr) > 0:
                alternative_server_uid = alternative_server_attr['uid'][0]
                alternative_server_uid = alternative_server_uid.replace(
                    '$', '')
                if len(alternative_server_uid) > 0:
                    return '%s.%s' % (alternative_server_uid, domainname)

        # fallback
        return '%s.%s' % (school.get_dc_name_fallback(), domainname)
Example #21
0
	def get_administrative_group_name(self, group_type, domain_controller=True, ou_specific=False, as_dn=False):
		if domain_controller == 'both':
			return flatten([self.get_administrative_group_name(group_type, True, ou_specific, as_dn), self.get_administrative_group_name(group_type, False, ou_specific, as_dn)])
		if ou_specific == 'both':
			return flatten([self.get_administrative_group_name(group_type, domain_controller, False, as_dn), self.get_administrative_group_name(group_type, domain_controller, True, as_dn)])
		if group_type == 'administrative':
			name = 'Verwaltungsnetz'
		else:
			name = 'Edukativnetz'
		if domain_controller:
			name = 'DC-%s' % name
		else:
			name = 'Member-%s' % name
		if ou_specific:
			name = 'OU%s-%s' % (self.name.lower(), name)
		if as_dn:
			return 'cn=%s,cn=ucsschool,cn=groups,%s' % (name, ucr.get('ldap/base'))
		else:
			return name
Example #22
0
 def get_container(cls, school=None):
     from ucsschool.lib.models.school import School
     if school:
         return School.cache(school).dn
     return ucr.get('ldap/base')
Example #23
0
	def get_container(cls, school=None):
		return 'cn=domain,cn=mail,%s' % ucr.get('ldap/base')
Example #24
0
	def cn_name(cls, name, default):
		ucr_var = 'ucsschool/ldap/default/container/%s' % name
		return ucr.get(ucr_var, default)
Example #25
0
	def get_container(cls, school=None):
		return ucr.get('ldap/base')
Example #26
0
	def _filter_local_schools(cls, schools, lo):
		if ucr.get('server/role') in ('domaincontroller_master', 'domaincontroller_backup'):
			return schools
		return [school for school in schools if any(ucr.get('ldap/hostdn', '').lower() == x.lower() for x in school.get_administrative_server_names(lo) + school.get_educational_server_names(lo))]
Example #27
0
 def get_samba_home_drive(self):
     return ucr.get('ucsschool/import/set/homedrive')
Example #28
0
	def group_name(self, prefix_var, default_prefix):
		ucr_var = 'ucsschool/ldap/default/groupprefix/%s' % prefix_var
		name_part = ucr.get(ucr_var, default_prefix)
		school_part = self.name.lower()
		return '%s%s' % (name_part, school_part)
Example #29
0
	def get_dhcp_service(self, hostname=None):
		return DHCPService.cache(self.name.lower(), self.name, hostname=hostname, domainname=ucr.get('domainname'))
Example #30
0
	def get_umc_policy_dn(self, name):
		# at least the default ones should exist due to the join script
		return ucr.get('ucsschool/ldap/default/policy/umc/%s' % name, 'cn=ucsschool-umc-%s-default,cn=UMC,cn=policies,%s' % (name, ucr.get('ldap/base')))